Enter the directory of the maca folder on your drive and the name of the tissue you want to analyze.

tissue_of_interest = "Bladder"

Load the requisite packages and some additional helper functions.

# read the metadata to get the plates we want
droplet_metadata_filename = here('00_data_ingest', '01_droplet_raw_data', 'metadata_droplet.csv')
droplet_metadata <- read.csv(droplet_metadata_filename, sep=",", header = TRUE)
colnames(droplet_metadata)[1] <- "channel"
droplet_metadata

Subset the metadata on the tissue.

tissue_metadata = filter(droplet_metadata, tissue == tissue_of_interest)[,c('channel','tissue','subtissue','mouse.sex', 'mouse.id')]
tissue_metadata

Use only the metadata rows corresponding to Bladder plates. Make a plate barcode dataframe to “expand” the per-plate metadata to be per-cell.

# Load the gene names and set the metadata columns by opening the first file
subfolder = paste0(tissue_of_interest, '-', tissue_metadata$channel[1])
raw.data <- Read10X(data.dir = here('00_data_ingest', '01_droplet_raw_data', 'droplet', subfolder))
colnames(raw.data) <- lapply(colnames(raw.data), function(x) paste0(tissue_metadata$channel[1], '_', x))
meta.data = data.frame(row.names = colnames(raw.data))
meta.data['channel'] = tissue_metadata$channel[1]
if (length(tissue_metadata$channel) > 1){
  # Some tissues, like Thymus and Heart had only one channel
  for(i in 2:nrow(tissue_metadata)){
    subfolder = paste0(tissue_of_interest, '-', tissue_metadata$channel[i])
    new.data <- Read10X(data.dir = here('00_data_ingest', '01_droplet_raw_data', 'droplet', subfolder))
    colnames(new.data) <- lapply(colnames(new.data), function(x) paste0(tissue_metadata$channel[i], '_', x))
    
    new.metadata = data.frame(row.names = colnames(new.data))
    new.metadata['channel'] = tissue_metadata$channel[i]
    
    raw.data = cbind(raw.data, new.data)
    meta.data = rbind(meta.data, new.metadata)
  }
}
rnames = row.names(meta.data)
meta.data <- merge(meta.data, tissue_metadata, sort = F)
row.names(meta.data) <- rnames
dim(raw.data)
[1] 23433  2500
corner(raw.data)
[1] 0 0 0 1 0
head(meta.data)

Process the raw data and load it into the Seurat object.

# Find ERCC's, compute the percent ERCC, and drop them from the raw data.
erccs <- grep(pattern = "^ERCC-", x = rownames(x = raw.data), value = TRUE)
percent.ercc <- Matrix::colSums(raw.data[erccs, ])/Matrix::colSums(raw.data)
ercc.index <- grep(pattern = "^ERCC-", x = rownames(x = raw.data), value = FALSE)
raw.data <- raw.data[-ercc.index,]
# Create the Seurat object with all the data
tiss <- CreateSeuratObject(raw.data = raw.data, project = tissue_of_interest, 
                    min.cells = 5, min.genes = 5)
tiss <- AddMetaData(object = tiss, meta.data)
tiss <- AddMetaData(object = tiss, percent.ercc, col.name = "percent.ercc")
# Create metadata columns for cell_ontology_classs and subcell_ontology_classs
tiss@meta.data[,'cell_ontology_class'] <- NA
tiss@meta.data[,'subcell_ontology_class'] <- NA

Calculate percent ribosomal genes.

ribo.genes <- grep(pattern = "^Rp[sl][[:digit:]]", x = rownames(x = tiss@data), value = TRUE)
percent.ribo <- Matrix::colSums(tiss@raw.data[ribo.genes, ])/Matrix::colSums(tiss@raw.data)
tiss <- AddMetaData(object = tiss, metadata = percent.ribo, col.name = "percent.ribo")

A sanity check: genes per cell vs reads per cell.

GenePlot(object = tiss, gene1 = "nUMI", gene2 = "nGene", use.raw=T)

Filter out cells with few reads and few genes.

tiss <- FilterCells(object = tiss, subset.names = c("nGene", "nUMI"), 
    low.thresholds = c(500, 1000), high.thresholds = c(25000, 5000000))

Normalize the data, then regress out correlation with total reads

tiss <- NormalizeData(object = tiss)
Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
tiss <- ScaleData(object = tiss)
[1] "Scaling data matrix"

  |                                                                          
  |                                                                    |   0%
  |                                                                          
  |====================================================================| 100%
tiss <- FindVariableGenes(object = tiss, do.plot = TRUE, x.high.cutoff = Inf, y.cutoff = 0.5)
Calculating gene means
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Calculating gene variance to mean ratios
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|

Run Principal Component Analysis.

tiss <- RunPCA(object = tiss, do.print = FALSE)
tiss <- ProjectPCA(object = tiss, do.print = FALSE)

Later on (in FindClusters and TSNE) you will pick a number of principal components to use. This has the effect of keeping the major directions of variation in the data and, ideally, supressing noise. There is no correct answer to the number to use, but a decent rule of thumb is to go until the plot plateaus.

PCElbowPlot(object = tiss)

Choose the number of principal components to use.

# Set number of principal components. 
n.pcs = 10

The clustering is performed based on a nearest neighbors graph. Cells that have similar expression will be joined together. The Louvain algorithm looks for groups of cells with high modularity–more connections within the group than between groups. The resolution parameter determines the scale…higher resolution will give more clusters, lower resolution will give fewer.

For the top-level clustering, aim to under-cluster instead of over-cluster. It will be easy to subset groups and further analyze them below.

# Set resolution 
res.used <- 0.4
tiss <- FindClusters(object = tiss, reduction.type = "pca", dims.use = 1:n.pcs, 
    resolution = res.used, print.output = 0, save.SNN = TRUE, force.recalc = TRUE)

To visualize

# If cells are too spread out, you can raise the perplexity. If you have few cells, try a lower perplexity (but never less than 10).
tiss <- RunTSNE(object = tiss, dims.use = 1:n.pcs, seed.use = 10, perplexity=30, dim.embed = 2)
# note that you can set do.label=T to help label individual clusters
TSNEPlot(object = tiss, do.label = T)

Check expression of genes of interset.

VlnPlot(tiss, genes_to_check)

Dotplots let you see the intensity of exppression and the fraction of cells expressing for each of your genes of interest.

How big are the clusters?

table(tiss@ident)

  0   1   2   3   4   5   6   7 
521 492 491 420 256 190  73  57 

Which markers identify a specific cluster?

clust.markers <- FindMarkers(object = tiss, ident.1 = 2, ident.2 = 1, only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25)
print(x = head(x= clust.markers, n = 10))

You can also compute all markers for all clusters at once. This may take some time.

tiss.markers <- FindAllMarkers(object = tiss, only.pos = TRUE, min.pct = 0.25, thresh.use = 0.25)

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~01m 32s      
   |++                                                | 2 % ~01m 24s      
   |++                                                | 3 % ~01m 22s      
   |+++                                               | 4 % ~01m 19s      
   |+++                                               | 5 % ~01m 17s      
   |++++                                              | 6 % ~01m 15s      
   |++++                                              | 7 % ~01m 14s      
   |+++++                                             | 8 % ~01m 14s      
   |+++++                                             | 9 % ~01m 13s      
   |++++++                                            | 10% ~01m 12s      
   |++++++                                            | 11% ~01m 11s      
   |+++++++                                           | 12% ~01m 11s      
   |+++++++                                           | 13% ~01m 10s      
   |++++++++                                          | 14% ~01m 09s      
   |++++++++                                          | 15% ~01m 08s      
   |+++++++++                                         | 16% ~01m 07s      
   |+++++++++                                         | 17% ~01m 06s      
   |++++++++++                                        | 18% ~01m 05s      
   |++++++++++                                        | 19% ~01m 04s      
   |+++++++++++                                       | 20% ~01m 03s      
   |+++++++++++                                       | 21% ~01m 03s      
   |++++++++++++                                      | 22% ~01m 02s      
   |++++++++++++                                      | 23% ~01m 01s      
   |+++++++++++++                                     | 24% ~01m 01s      
   |+++++++++++++                                     | 25% ~60s          
   |++++++++++++++                                    | 26% ~59s          
   |++++++++++++++                                    | 27% ~58s          
   |+++++++++++++++                                   | 28% ~57s          
   |+++++++++++++++                                   | 29% ~56s          
   |++++++++++++++++                                  | 30% ~55s          
   |++++++++++++++++                                  | 31% ~55s          
   |+++++++++++++++++                                 | 32% ~54s          
   |+++++++++++++++++                                 | 33% ~54s          
   |++++++++++++++++++                                | 34% ~53s          
   |++++++++++++++++++                                | 35% ~52s          
   |+++++++++++++++++++                               | 36% ~51s          
   |+++++++++++++++++++                               | 37% ~50s          
   |++++++++++++++++++++                              | 38% ~49s          
   |++++++++++++++++++++                              | 39% ~48s          
   |+++++++++++++++++++++                             | 40% ~48s          
   |+++++++++++++++++++++                             | 41% ~47s          
   |++++++++++++++++++++++                            | 42% ~46s          
   |++++++++++++++++++++++                            | 43% ~45s          
   |+++++++++++++++++++++++                           | 44% ~44s          
   |+++++++++++++++++++++++                           | 45% ~44s          
   |++++++++++++++++++++++++                          | 46% ~43s          
   |++++++++++++++++++++++++                          | 47% ~42s          
   |+++++++++++++++++++++++++                         | 48% ~41s          
   |+++++++++++++++++++++++++                         | 49% ~40s          
   |++++++++++++++++++++++++++                        | 51% ~39s          
   |++++++++++++++++++++++++++                        | 52% ~39s          
   |+++++++++++++++++++++++++++                       | 53% ~38s          
   |+++++++++++++++++++++++++++                       | 54% ~37s          
   |++++++++++++++++++++++++++++                      | 55% ~36s          
   |++++++++++++++++++++++++++++                      | 56% ~36s          
   |+++++++++++++++++++++++++++++                     | 57% ~35s          
   |+++++++++++++++++++++++++++++                     | 58% ~34s          
   |++++++++++++++++++++++++++++++                    | 59% ~33s          
   |++++++++++++++++++++++++++++++                    | 60% ~32s          
   |+++++++++++++++++++++++++++++++                   | 61% ~31s          
   |+++++++++++++++++++++++++++++++                   | 62% ~31s          
   |++++++++++++++++++++++++++++++++                  | 63% ~30s          
   |++++++++++++++++++++++++++++++++                  | 64% ~29s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~28s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~28s          
   |++++++++++++++++++++++++++++++++++                | 67% ~27s          
   |++++++++++++++++++++++++++++++++++                | 68% ~26s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~25s          
   |+++++++++++++++++++++++++++++++++++               | 70% ~24s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~24s          
   |++++++++++++++++++++++++++++++++++++              | 72% ~23s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~22s          
   |+++++++++++++++++++++++++++++++++++++             | 74% ~21s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~21s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~20s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~19s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~18s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~17s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~17s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~16s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~15s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~14s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~13s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~13s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~12s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~11s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~10s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~09s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~07s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~06s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~05s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~04s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 01m 23s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~01m 30s      
   |++                                                | 2 % ~01m 29s      
   |++                                                | 3 % ~01m 40s      
   |+++                                               | 4 % ~01m 35s      
   |+++                                               | 5 % ~01m 30s      
   |++++                                              | 6 % ~01m 27s      
   |++++                                              | 7 % ~01m 25s      
   |+++++                                             | 8 % ~01m 23s      
   |+++++                                             | 9 % ~01m 22s      
   |++++++                                            | 10% ~01m 21s      
   |++++++                                            | 11% ~01m 20s      
   |+++++++                                           | 12% ~01m 19s      
   |+++++++                                           | 13% ~01m 18s      
   |++++++++                                          | 14% ~01m 17s      
   |++++++++                                          | 15% ~01m 16s      
   |+++++++++                                         | 16% ~01m 15s      
   |+++++++++                                         | 18% ~01m 14s      
   |++++++++++                                        | 19% ~01m 13s      
   |++++++++++                                        | 20% ~01m 12s      
   |+++++++++++                                       | 21% ~01m 12s      
   |+++++++++++                                       | 22% ~01m 11s      
   |++++++++++++                                      | 23% ~01m 10s      
   |++++++++++++                                      | 24% ~01m 09s      
   |+++++++++++++                                     | 25% ~01m 08s      
   |+++++++++++++                                     | 26% ~01m 08s      
   |++++++++++++++                                    | 27% ~01m 07s      
   |++++++++++++++                                    | 28% ~01m 06s      
   |+++++++++++++++                                   | 29% ~01m 05s      
   |+++++++++++++++                                   | 30% ~01m 04s      
   |++++++++++++++++                                  | 31% ~01m 03s      
   |++++++++++++++++                                  | 32% ~01m 02s      
   |+++++++++++++++++                                 | 33% ~01m 01s      
   |++++++++++++++++++                                | 34% ~01m 00s      
   |++++++++++++++++++                                | 35% ~59s          
   |+++++++++++++++++++                               | 36% ~58s          
   |+++++++++++++++++++                               | 37% ~57s          
   |++++++++++++++++++++                              | 38% ~56s          
   |++++++++++++++++++++                              | 39% ~55s          
   |+++++++++++++++++++++                             | 40% ~54s          
   |+++++++++++++++++++++                             | 41% ~53s          
   |++++++++++++++++++++++                            | 42% ~52s          
   |++++++++++++++++++++++                            | 43% ~51s          
   |+++++++++++++++++++++++                           | 44% ~50s          
   |+++++++++++++++++++++++                           | 45% ~49s          
   |++++++++++++++++++++++++                          | 46% ~48s          
   |++++++++++++++++++++++++                          | 47% ~47s          
   |+++++++++++++++++++++++++                         | 48% ~46s          
   |+++++++++++++++++++++++++                         | 49% ~46s          
   |++++++++++++++++++++++++++                        | 51% ~45s          
   |++++++++++++++++++++++++++                        | 52% ~44s          
   |+++++++++++++++++++++++++++                       | 53% ~43s          
   |+++++++++++++++++++++++++++                       | 54% ~42s          
   |++++++++++++++++++++++++++++                      | 55% ~41s          
   |++++++++++++++++++++++++++++                      | 56% ~40s          
   |+++++++++++++++++++++++++++++                     | 57% ~39s          
   |+++++++++++++++++++++++++++++                     | 58% ~38s          
   |++++++++++++++++++++++++++++++                    | 59% ~37s          
   |++++++++++++++++++++++++++++++                    | 60% ~36s          
   |+++++++++++++++++++++++++++++++                   | 61% ~35s          
   |+++++++++++++++++++++++++++++++                   | 62% ~34s          
   |++++++++++++++++++++++++++++++++                  | 63% ~33s          
   |++++++++++++++++++++++++++++++++                  | 64% ~32s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~32s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~31s          
   |++++++++++++++++++++++++++++++++++                | 67% ~30s          
   |+++++++++++++++++++++++++++++++++++               | 68% ~29s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~28s          
   |++++++++++++++++++++++++++++++++++++              | 70% ~27s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~26s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~25s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~24s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~23s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~22s          
   |+++++++++++++++++++++++++++++++++++++++           | 76% ~21s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~20s          
   |++++++++++++++++++++++++++++++++++++++++          | 78% ~19s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~18s          
   |+++++++++++++++++++++++++++++++++++++++++         | 80% ~18s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~17s          
   |++++++++++++++++++++++++++++++++++++++++++        | 82% ~16s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~15s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~14s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~13s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~12s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~11s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~10s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~09s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~07s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~06s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~06s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~05s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~04s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 01m 29s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~01m 16s      
   |++                                                | 2 % ~01m 19s      
   |++                                                | 3 % ~01m 17s      
   |+++                                               | 4 % ~01m 17s      
   |+++                                               | 5 % ~01m 16s      
   |++++                                              | 6 % ~01m 15s      
   |++++                                              | 7 % ~01m 14s      
   |+++++                                             | 8 % ~01m 13s      
   |+++++                                             | 9 % ~01m 12s      
   |++++++                                            | 10% ~01m 13s      
   |++++++                                            | 11% ~01m 12s      
   |+++++++                                           | 12% ~01m 11s      
   |+++++++                                           | 13% ~01m 11s      
   |++++++++                                          | 14% ~01m 10s      
   |++++++++                                          | 15% ~01m 09s      
   |+++++++++                                         | 16% ~01m 08s      
   |+++++++++                                         | 17% ~01m 07s      
   |++++++++++                                        | 18% ~01m 06s      
   |++++++++++                                        | 19% ~01m 05s      
   |+++++++++++                                       | 20% ~01m 05s      
   |+++++++++++                                       | 21% ~01m 05s      
   |++++++++++++                                      | 22% ~01m 04s      
   |++++++++++++                                      | 23% ~01m 03s      
   |+++++++++++++                                     | 24% ~01m 02s      
   |+++++++++++++                                     | 25% ~01m 01s      
   |++++++++++++++                                    | 26% ~01m 00s      
   |++++++++++++++                                    | 27% ~59s          
   |+++++++++++++++                                   | 28% ~01m 01s      
   |+++++++++++++++                                   | 29% ~01m 00s      
   |++++++++++++++++                                  | 30% ~59s          
   |++++++++++++++++                                  | 31% ~58s          
   |+++++++++++++++++                                 | 32% ~57s          
   |+++++++++++++++++                                 | 33% ~56s          
   |++++++++++++++++++                                | 34% ~55s          
   |++++++++++++++++++                                | 35% ~54s          
   |+++++++++++++++++++                               | 36% ~53s          
   |+++++++++++++++++++                               | 37% ~52s          
   |++++++++++++++++++++                              | 38% ~52s          
   |++++++++++++++++++++                              | 39% ~51s          
   |+++++++++++++++++++++                             | 40% ~50s          
   |+++++++++++++++++++++                             | 41% ~49s          
   |++++++++++++++++++++++                            | 42% ~48s          
   |++++++++++++++++++++++                            | 43% ~47s          
   |+++++++++++++++++++++++                           | 44% ~46s          
   |+++++++++++++++++++++++                           | 45% ~46s          
   |++++++++++++++++++++++++                          | 46% ~45s          
   |++++++++++++++++++++++++                          | 47% ~44s          
   |+++++++++++++++++++++++++                         | 48% ~43s          
   |+++++++++++++++++++++++++                         | 49% ~42s          
   |++++++++++++++++++++++++++                        | 51% ~42s          
   |++++++++++++++++++++++++++                        | 52% ~41s          
   |+++++++++++++++++++++++++++                       | 53% ~40s          
   |+++++++++++++++++++++++++++                       | 54% ~39s          
   |++++++++++++++++++++++++++++                      | 55% ~38s          
   |++++++++++++++++++++++++++++                      | 56% ~38s          
   |+++++++++++++++++++++++++++++                     | 57% ~37s          
   |+++++++++++++++++++++++++++++                     | 58% ~36s          
   |++++++++++++++++++++++++++++++                    | 59% ~35s          
   |++++++++++++++++++++++++++++++                    | 60% ~34s          
   |+++++++++++++++++++++++++++++++                   | 61% ~33s          
   |+++++++++++++++++++++++++++++++                   | 62% ~32s          
   |++++++++++++++++++++++++++++++++                  | 63% ~31s          
   |++++++++++++++++++++++++++++++++                  | 64% ~31s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~30s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~29s          
   |++++++++++++++++++++++++++++++++++                | 67% ~28s          
   |++++++++++++++++++++++++++++++++++                | 68% ~27s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~26s          
   |+++++++++++++++++++++++++++++++++++               | 70% ~25s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~25s          
   |++++++++++++++++++++++++++++++++++++              | 72% ~24s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~23s          
   |+++++++++++++++++++++++++++++++++++++             | 74% ~22s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~21s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~20s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~20s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~19s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~18s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~17s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~16s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~15s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~14s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~14s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~13s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~12s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~11s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~10s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~09s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~07s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~06s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~05s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~04s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 01m 24s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~01m 26s      
   |++                                                | 2 % ~01m 23s      
   |++                                                | 3 % ~01m 23s      
   |+++                                               | 4 % ~01m 22s      
   |+++                                               | 5 % ~01m 30s      
   |++++                                              | 6 % ~01m 27s      
   |++++                                              | 7 % ~01m 25s      
   |+++++                                             | 9 % ~01m 23s      
   |+++++                                             | 10% ~01m 22s      
   |++++++                                            | 11% ~01m 20s      
   |++++++                                            | 12% ~01m 19s      
   |+++++++                                           | 13% ~01m 18s      
   |+++++++                                           | 14% ~01m 17s      
   |++++++++                                          | 15% ~01m 15s      
   |++++++++                                          | 16% ~01m 14s      
   |+++++++++                                         | 17% ~01m 13s      
   |++++++++++                                        | 18% ~01m 13s      
   |++++++++++                                        | 19% ~01m 11s      
   |+++++++++++                                       | 20% ~01m 10s      
   |+++++++++++                                       | 21% ~01m 09s      
   |++++++++++++                                      | 22% ~01m 08s      
   |++++++++++++                                      | 23% ~01m 07s      
   |+++++++++++++                                     | 24% ~01m 06s      
   |+++++++++++++                                     | 26% ~01m 05s      
   |++++++++++++++                                    | 27% ~01m 04s      
   |++++++++++++++                                    | 28% ~01m 03s      
   |+++++++++++++++                                   | 29% ~01m 02s      
   |+++++++++++++++                                   | 30% ~01m 01s      
   |++++++++++++++++                                  | 31% ~01m 00s      
   |++++++++++++++++                                  | 32% ~59s          
   |+++++++++++++++++                                 | 33% ~58s          
   |++++++++++++++++++                                | 34% ~57s          
   |++++++++++++++++++                                | 35% ~57s          
   |+++++++++++++++++++                               | 36% ~56s          
   |+++++++++++++++++++                               | 37% ~55s          
   |++++++++++++++++++++                              | 38% ~54s          
   |++++++++++++++++++++                              | 39% ~53s          
   |+++++++++++++++++++++                             | 40% ~52s          
   |+++++++++++++++++++++                             | 41% ~51s          
   |++++++++++++++++++++++                            | 43% ~50s          
   |++++++++++++++++++++++                            | 44% ~49s          
   |+++++++++++++++++++++++                           | 45% ~48s          
   |+++++++++++++++++++++++                           | 46% ~47s          
   |++++++++++++++++++++++++                          | 47% ~47s          
   |++++++++++++++++++++++++                          | 48% ~46s          
   |+++++++++++++++++++++++++                         | 49% ~46s          
   |+++++++++++++++++++++++++                         | 50% ~45s          
   |++++++++++++++++++++++++++                        | 51% ~44s          
   |+++++++++++++++++++++++++++                       | 52% ~43s          
   |+++++++++++++++++++++++++++                       | 53% ~42s          
   |++++++++++++++++++++++++++++                      | 54% ~41s          
   |++++++++++++++++++++++++++++                      | 55% ~40s          
   |+++++++++++++++++++++++++++++                     | 56% ~39s          
   |+++++++++++++++++++++++++++++                     | 57% ~38s          
   |++++++++++++++++++++++++++++++                    | 59% ~37s          
   |++++++++++++++++++++++++++++++                    | 60% ~36s          
   |+++++++++++++++++++++++++++++++                   | 61% ~35s          
   |+++++++++++++++++++++++++++++++                   | 62% ~34s          
   |++++++++++++++++++++++++++++++++                  | 63% ~33s          
   |++++++++++++++++++++++++++++++++                  | 64% ~32s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~31s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~30s          
   |++++++++++++++++++++++++++++++++++                | 67% ~29s          
   |+++++++++++++++++++++++++++++++++++               | 68% ~28s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~27s          
   |++++++++++++++++++++++++++++++++++++              | 70% ~26s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~25s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~24s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~23s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~22s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~21s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~20s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~20s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~19s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~18s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~17s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~16s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~15s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 84% ~14s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~13s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~12s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~11s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~10s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~09s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 90% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~07s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~06s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~06s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~05s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~04s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 01m 26s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~01m 23s      
   |++                                                | 2 % ~01m 22s      
   |++                                                | 3 % ~01m 21s      
   |+++                                               | 4 % ~01m 21s      
   |+++                                               | 5 % ~01m 21s      
   |++++                                              | 6 % ~01m 21s      
   |++++                                              | 7 % ~01m 20s      
   |+++++                                             | 8 % ~01m 19s      
   |+++++                                             | 9 % ~01m 18s      
   |++++++                                            | 11% ~01m 18s      
   |++++++                                            | 12% ~01m 17s      
   |+++++++                                           | 13% ~01m 17s      
   |+++++++                                           | 14% ~01m 16s      
   |++++++++                                          | 15% ~01m 15s      
   |++++++++                                          | 16% ~01m 14s      
   |+++++++++                                         | 17% ~01m 13s      
   |+++++++++                                         | 18% ~01m 12s      
   |++++++++++                                        | 19% ~01m 11s      
   |++++++++++                                        | 20% ~01m 10s      
   |+++++++++++                                       | 21% ~01m 09s      
   |++++++++++++                                      | 22% ~01m 08s      
   |++++++++++++                                      | 23% ~01m 07s      
   |+++++++++++++                                     | 24% ~01m 06s      
   |+++++++++++++                                     | 25% ~01m 05s      
   |++++++++++++++                                    | 26% ~01m 04s      
   |++++++++++++++                                    | 27% ~01m 03s      
   |+++++++++++++++                                   | 28% ~01m 02s      
   |+++++++++++++++                                   | 29% ~01m 02s      
   |++++++++++++++++                                  | 31% ~01m 01s      
   |++++++++++++++++                                  | 32% ~60s          
   |+++++++++++++++++                                 | 33% ~59s          
   |+++++++++++++++++                                 | 34% ~58s          
   |++++++++++++++++++                                | 35% ~57s          
   |++++++++++++++++++                                | 36% ~56s          
   |+++++++++++++++++++                               | 37% ~55s          
   |+++++++++++++++++++                               | 38% ~54s          
   |++++++++++++++++++++                              | 39% ~53s          
   |++++++++++++++++++++                              | 40% ~53s          
   |+++++++++++++++++++++                             | 41% ~52s          
   |++++++++++++++++++++++                            | 42% ~51s          
   |++++++++++++++++++++++                            | 43% ~50s          
   |+++++++++++++++++++++++                           | 44% ~49s          
   |+++++++++++++++++++++++                           | 45% ~48s          
   |++++++++++++++++++++++++                          | 46% ~47s          
   |++++++++++++++++++++++++                          | 47% ~47s          
   |+++++++++++++++++++++++++                         | 48% ~46s          
   |+++++++++++++++++++++++++                         | 49% ~45s          
   |++++++++++++++++++++++++++                        | 51% ~44s          
   |++++++++++++++++++++++++++                        | 52% ~43s          
   |+++++++++++++++++++++++++++                       | 53% ~42s          
   |+++++++++++++++++++++++++++                       | 54% ~41s          
   |++++++++++++++++++++++++++++                      | 55% ~40s          
   |++++++++++++++++++++++++++++                      | 56% ~39s          
   |+++++++++++++++++++++++++++++                     | 57% ~38s          
   |+++++++++++++++++++++++++++++                     | 58% ~38s          
   |++++++++++++++++++++++++++++++                    | 59% ~37s          
   |++++++++++++++++++++++++++++++                    | 60% ~36s          
   |+++++++++++++++++++++++++++++++                   | 61% ~35s          
   |++++++++++++++++++++++++++++++++                  | 62% ~34s          
   |++++++++++++++++++++++++++++++++                  | 63% ~33s          
   |+++++++++++++++++++++++++++++++++                 | 64% ~32s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~31s          
   |++++++++++++++++++++++++++++++++++                | 66% ~30s          
   |++++++++++++++++++++++++++++++++++                | 67% ~29s          
   |+++++++++++++++++++++++++++++++++++               | 68% ~28s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~27s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~26s          
   |++++++++++++++++++++++++++++++++++++              | 72% ~25s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~24s          
   |+++++++++++++++++++++++++++++++++++++             | 74% ~24s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~23s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~22s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~21s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~20s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~19s          
   |++++++++++++++++++++++++++++++++++++++++         | 80% ~18s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~17s          
   |++++++++++++++++++++++++++++++++++++++++++        | 82% ~16s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~15s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 84% ~14s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~13s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~12s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~11s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~10s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~09s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~09s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~08s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~07s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~06s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~05s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~04s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 01m 29s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~01m 26s      
   |++                                                | 2 % ~01m 26s      
   |++                                                | 3 % ~01m 24s      
   |+++                                               | 4 % ~01m 23s      
   |+++                                               | 5 % ~01m 22s      
   |++++                                              | 6 % ~01m 21s      
   |++++                                              | 7 % ~01m 24s      
   |+++++                                             | 9 % ~01m 22s      
   |+++++                                             | 10% ~01m 21s      
   |++++++                                            | 11% ~01m 20s      
   |++++++                                            | 12% ~01m 19s      
   |+++++++                                           | 13% ~01m 18s      
   |+++++++                                           | 14% ~01m 17s      
   |++++++++                                          | 15% ~01m 16s      
   |++++++++                                          | 16% ~01m 15s      
   |+++++++++                                         | 17% ~01m 14s      
   |++++++++++                                        | 18% ~01m 12s      
   |++++++++++                                        | 19% ~01m 11s      
   |+++++++++++                                       | 20% ~01m 10s      
   |+++++++++++                                       | 21% ~01m 09s      
   |++++++++++++                                      | 22% ~01m 08s      
   |++++++++++++                                      | 23% ~01m 07s      
   |+++++++++++++                                     | 24% ~01m 06s      
   |+++++++++++++                                     | 26% ~01m 05s      
   |++++++++++++++                                    | 27% ~01m 04s      
   |++++++++++++++                                    | 28% ~01m 03s      
   |+++++++++++++++                                   | 29% ~01m 02s      
   |+++++++++++++++                                   | 30% ~01m 01s      
   |++++++++++++++++                                  | 31% ~59s          
   |++++++++++++++++                                  | 32% ~58s          
   |+++++++++++++++++                                 | 33% ~57s          
   |++++++++++++++++++                                | 34% ~56s          
   |++++++++++++++++++                                | 35% ~55s          
   |+++++++++++++++++++                               | 36% ~55s          
   |+++++++++++++++++++                               | 37% ~54s          
   |++++++++++++++++++++                              | 38% ~53s          
   |++++++++++++++++++++                              | 39% ~52s          
   |+++++++++++++++++++++                             | 40% ~51s          
   |+++++++++++++++++++++                             | 41% ~50s          
   |++++++++++++++++++++++                            | 43% ~49s          
   |++++++++++++++++++++++                            | 44% ~48s          
   |+++++++++++++++++++++++                           | 45% ~47s          
   |+++++++++++++++++++++++                           | 46% ~46s          
   |++++++++++++++++++++++++                          | 47% ~45s          
   |++++++++++++++++++++++++                          | 48% ~44s          
   |+++++++++++++++++++++++++                         | 49% ~43s          
   |+++++++++++++++++++++++++                         | 50% ~42s          
   |++++++++++++++++++++++++++                        | 51% ~41s          
   |+++++++++++++++++++++++++++                       | 52% ~40s          
   |+++++++++++++++++++++++++++                       | 53% ~40s          
   |++++++++++++++++++++++++++++                      | 54% ~39s          
   |++++++++++++++++++++++++++++                      | 55% ~38s          
   |+++++++++++++++++++++++++++++                     | 56% ~37s          
   |+++++++++++++++++++++++++++++                     | 57% ~36s          
   |++++++++++++++++++++++++++++++                    | 59% ~35s          
   |++++++++++++++++++++++++++++++                    | 60% ~35s          
   |+++++++++++++++++++++++++++++++                   | 61% ~34s          
   |+++++++++++++++++++++++++++++++                   | 62% ~33s          
   |++++++++++++++++++++++++++++++++                  | 63% ~32s          
   |++++++++++++++++++++++++++++++++                  | 64% ~31s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~30s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~29s          
   |++++++++++++++++++++++++++++++++++                | 67% ~28s          
   |+++++++++++++++++++++++++++++++++++               | 68% ~27s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~26s          
   |++++++++++++++++++++++++++++++++++++              | 70% ~25s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~24s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~24s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~23s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~22s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~21s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~20s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~19s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~18s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~17s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~16s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~15s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~15s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 84% ~14s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~13s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~12s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~11s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~10s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~09s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 90% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~07s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~06s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~05s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~05s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~04s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 01m 24s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~01m 48s      
   |++                                                | 2 % ~01m 46s      
   |++                                                | 3 % ~01m 45s      
   |+++                                               | 4 % ~01m 43s      
   |+++                                               | 5 % ~01m 42s      
   |++++                                              | 6 % ~01m 40s      
   |++++                                              | 7 % ~01m 39s      
   |+++++                                             | 8 % ~01m 38s      
   |+++++                                             | 9 % ~01m 38s      
   |++++++                                            | 10% ~01m 37s      
   |++++++                                            | 11% ~01m 36s      
   |+++++++                                           | 12% ~01m 35s      
   |+++++++                                           | 13% ~01m 34s      
   |++++++++                                          | 14% ~01m 33s      
   |++++++++                                          | 15% ~01m 31s      
   |+++++++++                                         | 16% ~01m 30s      
   |+++++++++                                         | 18% ~01m 29s      
   |++++++++++                                        | 19% ~01m 28s      
   |++++++++++                                        | 20% ~01m 27s      
   |+++++++++++                                       | 21% ~01m 25s      
   |+++++++++++                                       | 22% ~01m 24s      
   |++++++++++++                                      | 23% ~01m 23s      
   |++++++++++++                                      | 24% ~01m 22s      
   |+++++++++++++                                     | 25% ~01m 21s      
   |+++++++++++++                                     | 26% ~01m 20s      
   |++++++++++++++                                    | 27% ~01m 19s      
   |++++++++++++++                                    | 28% ~01m 18s      
   |+++++++++++++++                                   | 29% ~01m 16s      
   |+++++++++++++++                                   | 30% ~01m 15s      
   |++++++++++++++++                                  | 31% ~01m 14s      
   |++++++++++++++++                                  | 32% ~01m 13s      
   |+++++++++++++++++                                 | 33% ~01m 12s      
   |++++++++++++++++++                                | 34% ~01m 11s      
   |++++++++++++++++++                                | 35% ~01m 10s      
   |+++++++++++++++++++                               | 36% ~01m 09s      
   |+++++++++++++++++++                               | 37% ~01m 08s      
   |++++++++++++++++++++                              | 38% ~01m 07s      
   |++++++++++++++++++++                              | 39% ~01m 06s      
   |+++++++++++++++++++++                             | 40% ~01m 05s      
   |+++++++++++++++++++++                             | 41% ~01m 04s      
   |++++++++++++++++++++++                            | 42% ~01m 03s      
   |++++++++++++++++++++++                            | 43% ~01m 02s      
   |+++++++++++++++++++++++                           | 44% ~01m 01s      
   |+++++++++++++++++++++++                           | 45% ~59s          
   |++++++++++++++++++++++++                          | 46% ~58s          
   |++++++++++++++++++++++++                          | 47% ~57s          
   |+++++++++++++++++++++++++                         | 48% ~56s          
   |+++++++++++++++++++++++++                         | 49% ~55s          
   |++++++++++++++++++++++++++                        | 51% ~54s          
   |++++++++++++++++++++++++++                        | 52% ~53s          
   |+++++++++++++++++++++++++++                       | 53% ~51s          
   |+++++++++++++++++++++++++++                       | 54% ~50s          
   |++++++++++++++++++++++++++++                      | 55% ~49s          
   |++++++++++++++++++++++++++++                      | 56% ~48s          
   |+++++++++++++++++++++++++++++                     | 57% ~47s          
   |+++++++++++++++++++++++++++++                     | 58% ~46s          
   |++++++++++++++++++++++++++++++                    | 59% ~45s          
   |++++++++++++++++++++++++++++++                    | 60% ~44s          
   |+++++++++++++++++++++++++++++++                   | 61% ~43s          
   |+++++++++++++++++++++++++++++++                   | 62% ~42s          
   |++++++++++++++++++++++++++++++++                  | 63% ~41s          
   |++++++++++++++++++++++++++++++++                  | 64% ~40s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~39s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~38s          
   |++++++++++++++++++++++++++++++++++                | 67% ~37s          
   |+++++++++++++++++++++++++++++++++++               | 68% ~35s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~34s          
   |++++++++++++++++++++++++++++++++++++              | 70% ~33s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~32s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~31s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~30s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~29s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~27s          
   |+++++++++++++++++++++++++++++++++++++++           | 76% ~26s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~25s          
   |++++++++++++++++++++++++++++++++++++++++          | 78% ~24s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~23s          
   |+++++++++++++++++++++++++++++++++++++++++         | 80% ~22s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~21s          
   |++++++++++++++++++++++++++++++++++++++++++        | 82% ~20s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~18s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~17s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~16s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~15s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~14s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~13s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~12s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~10s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~09s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~08s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~07s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~06s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~05s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~03s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~02s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 01m 51s

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~02m 07s      
   |++                                                | 2 % ~02m 04s      
   |++                                                | 3 % ~02m 03s      
   |+++                                               | 4 % ~02m 02s      
   |+++                                               | 5 % ~02m 00s      
   |++++                                              | 6 % ~01m 59s      
   |++++                                              | 7 % ~01m 57s      
   |+++++                                             | 8 % ~01m 56s      
   |+++++                                             | 9 % ~01m 55s      
   |++++++                                            | 10% ~01m 54s      
   |++++++                                            | 11% ~01m 54s      
   |+++++++                                           | 12% ~01m 52s      
   |+++++++                                           | 13% ~01m 51s      
   |++++++++                                          | 14% ~01m 49s      
   |++++++++                                          | 15% ~01m 48s      
   |+++++++++                                         | 16% ~01m 47s      
   |+++++++++                                         | 17% ~01m 45s      
   |++++++++++                                        | 18% ~01m 44s      
   |++++++++++                                        | 19% ~01m 43s      
   |+++++++++++                                       | 20% ~01m 42s      
   |+++++++++++                                       | 21% ~01m 41s      
   |++++++++++++                                      | 22% ~01m 40s      
   |++++++++++++                                      | 23% ~01m 38s      
   |+++++++++++++                                     | 24% ~01m 37s      
   |+++++++++++++                                     | 26% ~01m 36s      
   |++++++++++++++                                    | 27% ~01m 35s      
   |++++++++++++++                                    | 28% ~01m 34s      
   |+++++++++++++++                                   | 29% ~01m 33s      
   |+++++++++++++++                                   | 30% ~01m 31s      
   |++++++++++++++++                                  | 31% ~01m 30s      
   |++++++++++++++++                                  | 32% ~01m 29s      
   |+++++++++++++++++                                 | 33% ~01m 27s      
   |+++++++++++++++++                                 | 34% ~01m 26s      
   |++++++++++++++++++                                | 35% ~01m 24s      
   |++++++++++++++++++                                | 36% ~01m 23s      
   |+++++++++++++++++++                               | 37% ~01m 21s      
   |+++++++++++++++++++                               | 38% ~01m 20s      
   |++++++++++++++++++++                              | 39% ~01m 19s      
   |++++++++++++++++++++                              | 40% ~01m 18s      
   |+++++++++++++++++++++                             | 41% ~01m 16s      
   |+++++++++++++++++++++                             | 42% ~01m 15s      
   |++++++++++++++++++++++                            | 43% ~01m 14s      
   |++++++++++++++++++++++                            | 44% ~01m 12s      
   |+++++++++++++++++++++++                           | 45% ~01m 11s      
   |+++++++++++++++++++++++                           | 46% ~01m 10s      
   |++++++++++++++++++++++++                          | 47% ~01m 08s      
   |++++++++++++++++++++++++                          | 48% ~01m 07s      
   |+++++++++++++++++++++++++                         | 49% ~01m 06s      
   |+++++++++++++++++++++++++                         | 50% ~01m 04s      
   |++++++++++++++++++++++++++                        | 51% ~01m 03s      
   |+++++++++++++++++++++++++++                       | 52% ~01m 02s      
   |+++++++++++++++++++++++++++                       | 53% ~01m 01s      
   |++++++++++++++++++++++++++++                      | 54% ~59s          
   |++++++++++++++++++++++++++++                      | 55% ~58s          
   |+++++++++++++++++++++++++++++                     | 56% ~57s          
   |+++++++++++++++++++++++++++++                     | 57% ~55s          
   |++++++++++++++++++++++++++++++                    | 58% ~54s          
   |++++++++++++++++++++++++++++++                    | 59% ~53s          
   |+++++++++++++++++++++++++++++++                   | 60% ~52s          
   |+++++++++++++++++++++++++++++++                   | 61% ~50s          
   |++++++++++++++++++++++++++++++++                  | 62% ~49s          
   |++++++++++++++++++++++++++++++++                  | 63% ~48s          
   |+++++++++++++++++++++++++++++++++                 | 64% ~46s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~45s          
   |++++++++++++++++++++++++++++++++++                | 66% ~44s          
   |++++++++++++++++++++++++++++++++++                | 67% ~43s          
   |+++++++++++++++++++++++++++++++++++               | 68% ~41s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~40s          
   |++++++++++++++++++++++++++++++++++++              | 70% ~39s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~37s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~36s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~34s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~33s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~32s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~30s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~29s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~28s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~26s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~25s          
   |+++++++++++++++++++++++++++++++++++++++++         | 82% ~24s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~22s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~21s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~20s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~18s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~17s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~16s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~15s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~13s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~12s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~11s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~09s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~08s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~07s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~05s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~04s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~03s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 02m 08s
save.image("bladder_droplet_image.RData")

Display the top markers you computed above.

tiss.markers %>% group_by(cluster) %>% top_n(20, avg_logFC)

tiss= BuildClusterTree(tiss)
[1] "Finished averaging RNA for cluster 0"
[1] "Finished averaging RNA for cluster 1"
[1] "Finished averaging RNA for cluster 2"
[1] "Finished averaging RNA for cluster 3"
[1] "Finished averaging RNA for cluster 4"
[1] "Finished averaging RNA for cluster 5"
[1] "Finished averaging RNA for cluster 6"
[1] "Finished averaging RNA for cluster 7"

Node11_markers = FindAllMarkersNode(tiss, node = 11)

   |                                                  | 0 % ~calculating  
   |+                                                 | 1 % ~06s          
   |++                                                | 2 % ~06s          
   |++                                                | 3 % ~05s          
   |+++                                               | 5 % ~05s          
   |+++                                               | 6 % ~05s          
   |++++                                              | 7 % ~05s          
   |+++++                                             | 8 % ~05s          
   |+++++                                             | 9 % ~05s          
   |++++++                                            | 10% ~05s          
   |++++++                                            | 12% ~05s          
   |+++++++                                           | 13% ~05s          
   |+++++++                                           | 14% ~05s          
   |++++++++                                          | 15% ~05s          
   |+++++++++                                         | 16% ~05s          
   |+++++++++                                         | 17% ~04s          
   |++++++++++                                        | 19% ~04s          
   |++++++++++                                        | 20% ~04s          
   |+++++++++++                                       | 21% ~04s          
   |++++++++++++                                      | 22% ~04s          
   |++++++++++++                                      | 23% ~04s          
   |+++++++++++++                                     | 24% ~04s          
   |+++++++++++++                                     | 26% ~04s          
   |++++++++++++++                                    | 27% ~04s          
   |++++++++++++++                                    | 28% ~04s          
   |+++++++++++++++                                   | 29% ~04s          
   |++++++++++++++++                                  | 30% ~04s          
   |++++++++++++++++                                  | 31% ~04s          
   |+++++++++++++++++                                 | 33% ~04s          
   |+++++++++++++++++                                 | 34% ~04s          
   |++++++++++++++++++                                | 35% ~04s          
   |+++++++++++++++++++                               | 36% ~03s          
   |+++++++++++++++++++                               | 37% ~03s          
   |++++++++++++++++++++                              | 38% ~03s          
   |++++++++++++++++++++                              | 40% ~03s          
   |+++++++++++++++++++++                             | 41% ~03s          
   |+++++++++++++++++++++                             | 42% ~03s          
   |++++++++++++++++++++++                            | 43% ~03s          
   |+++++++++++++++++++++++                           | 44% ~03s          
   |+++++++++++++++++++++++                           | 45% ~03s          
   |++++++++++++++++++++++++                          | 47% ~03s          
   |++++++++++++++++++++++++                          | 48% ~03s          
   |+++++++++++++++++++++++++                         | 49% ~03s          
   |+++++++++++++++++++++++++                         | 50% ~03s          
   |++++++++++++++++++++++++++                        | 51% ~03s          
   |+++++++++++++++++++++++++++                       | 52% ~03s          
   |+++++++++++++++++++++++++++                       | 53% ~03s          
   |++++++++++++++++++++++++++++                      | 55% ~03s          
   |++++++++++++++++++++++++++++                      | 56% ~02s          
   |+++++++++++++++++++++++++++++                     | 57% ~02s          
   |++++++++++++++++++++++++++++++                    | 58% ~02s          
   |++++++++++++++++++++++++++++++                    | 59% ~02s          
   |+++++++++++++++++++++++++++++++                   | 60% ~02s          
   |+++++++++++++++++++++++++++++++                   | 62% ~02s          
   |++++++++++++++++++++++++++++++++                  | 63% ~02s          
   |++++++++++++++++++++++++++++++++                  | 64% ~02s          
   |+++++++++++++++++++++++++++++++++                 | 65% ~02s          
   |++++++++++++++++++++++++++++++++++                | 66% ~02s          
   |++++++++++++++++++++++++++++++++++                | 67% ~02s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~02s          
   |+++++++++++++++++++++++++++++++++++               | 70% ~02s          
   |++++++++++++++++++++++++++++++++++++              | 71% ~02s          
   |+++++++++++++++++++++++++++++++++++++             | 72% ~01s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~01s          
   |++++++++++++++++++++++++++++++++++++++            | 74% ~01s          
   |++++++++++++++++++++++++++++++++++++++            | 76% ~01s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~01s          
   |+++++++++++++++++++++++++++++++++++++++           | 78% ~01s          
   |++++++++++++++++++++++++++++++++++++++++          | 79% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++         | 80% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++        | 84% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~01s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~01s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 94% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 05s

   |                                                  | 0 % ~calculating  
   |+                                                 | 2 % ~02s          
   |++                                                | 3 % ~02s          
   |+++                                               | 5 % ~02s          
   |++++                                              | 6 % ~02s          
   |++++                                              | 8 % ~02s          
   |+++++                                             | 9 % ~02s          
   |++++++                                            | 11% ~02s          
   |+++++++                                           | 12% ~02s          
   |++++++++                                          | 14% ~02s          
   |++++++++                                          | 16% ~02s          
   |+++++++++                                         | 17% ~02s          
   |++++++++++                                        | 19% ~02s          
   |+++++++++++                                       | 20% ~02s          
   |+++++++++++                                       | 22% ~02s          
   |++++++++++++                                      | 23% ~02s          
   |+++++++++++++                                     | 25% ~02s          
   |++++++++++++++                                    | 27% ~02s          
   |+++++++++++++++                                   | 28% ~02s          
   |+++++++++++++++                                   | 30% ~02s          
   |++++++++++++++++                                  | 31% ~01s          
   |+++++++++++++++++                                 | 33% ~01s          
   |++++++++++++++++++                                | 34% ~01s          
   |++++++++++++++++++                                | 36% ~01s          
   |+++++++++++++++++++                               | 38% ~01s          
   |++++++++++++++++++++                              | 39% ~01s          
   |+++++++++++++++++++++                             | 41% ~01s          
   |++++++++++++++++++++++                            | 42% ~01s          
   |++++++++++++++++++++++                            | 44% ~01s          
   |+++++++++++++++++++++++                           | 45% ~01s          
   |++++++++++++++++++++++++                          | 47% ~01s          
   |+++++++++++++++++++++++++                         | 48% ~01s          
   |+++++++++++++++++++++++++                         | 50% ~01s          
   |++++++++++++++++++++++++++                        | 52% ~01s          
   |+++++++++++++++++++++++++++                       | 53% ~01s          
   |++++++++++++++++++++++++++++                      | 55% ~01s          
   |+++++++++++++++++++++++++++++                     | 56% ~01s          
   |+++++++++++++++++++++++++++++                     | 58% ~01s          
   |++++++++++++++++++++++++++++++                    | 59% ~01s          
   |+++++++++++++++++++++++++++++++                   | 61% ~01s          
   |++++++++++++++++++++++++++++++++                  | 62% ~01s          
   |+++++++++++++++++++++++++++++++++                 | 64% ~01s          
   |+++++++++++++++++++++++++++++++++                 | 66% ~01s          
   |++++++++++++++++++++++++++++++++++                | 67% ~01s          
   |+++++++++++++++++++++++++++++++++++               | 69% ~01s          
   |++++++++++++++++++++++++++++++++++++              | 70% ~01s          
   |++++++++++++++++++++++++++++++++++++              | 72% ~01s          
   |+++++++++++++++++++++++++++++++++++++             | 73% ~01s          
   |++++++++++++++++++++++++++++++++++++++            | 75% ~01s          
   |+++++++++++++++++++++++++++++++++++++++           | 77% ~01s          
   |++++++++++++++++++++++++++++++++++++++++          | 78% ~00s          
   |++++++++++++++++++++++++++++++++++++++++          | 80% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++         | 81% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++        | 83% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 84% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 92% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
   |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 98% ~00s          
   |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed = 02s
Node11_markers %>% group_by(cluster) %>% top_n(30, avg_logFC)

Assigning cell type identity to clusters

At a coarse level, we can use canonical markers to match the unbiased clustering to known cell types:

# stash current cluster IDs
tiss <- StashIdent(object = tiss, save.name = "cluster.ids")
# enumerate current cluster IDs and the labels for them
cluster.ids <- c(0, 1, 2, 3, 4, 5, 6, 7)
free.cell_ontology_class <- c("Bladder mesenchymal cell", "Bladder mesenchymal cell", "Basal bladder epithelial cell", "Luminal bladder epithelial cell", "Luminal bladder epithelial cell", "Bladder mesenchymal cell", "Monocyte/Macrophage", "Endothelial cell")
cell_ontology_class <- c("bladder cell", "bladder cell" , "bladder urothelial cell", "bladder urothelial cell", "bladder urothelial cell", "bladder cell", "leukocyte", "endothelial cell")
in_cell_ontology = sapply(cell_ontology_class, function(x) is.element(x, cell_ontology$name))
if (!all(in_cell_ontology)) {
  message = paste0('"', cell_ontology_class[!in_cell_ontology], '" is not in the cell ontology\n')
  stop(message)
}
cell_ontology_id <- c("CL:1001319", "CL:1001319" , "CL_1001428", "CL_1001428", "CL_1001428", "CL:1001319", "CL_0000738", "CL_0000115")
tiss@meta.data[,'cell_ontology_class'] <- plyr::mapvalues(x = tiss@ident, from = cluster.ids, to = cell_ontology_class)
tiss@meta.data[,'cell_ontology_id'] <- plyr::mapvalues(x = tiss@ident, from = cluster.ids, to = cell_ontology_id)
tiss@meta.data[tiss@cell.names,'cell_ontology_class'] <- as.character(tiss@meta.data$cell_ontology_class)
tiss@meta.data[tiss@cell.names,'cell_ontology_id'] <- as.character(tiss@meta.data$cell_ontology_id)
TSNEPlot(object = tiss, do.label = TRUE, pt.size = 0.5, group.by='cell_ontology_class')

Checking for batch effects

Color by metadata, like plate barcode, to check for batch effects.

TSNEPlot(object = tiss, do.return = TRUE, group.by = "channel")

TSNEPlot(object = tiss, do.return = TRUE, group.by = "mouse.sex")

Print a table showing the count of cells in each identity category from each plate.

table(as.character(tiss@ident), as.character(tiss@meta.data$channel))
   
    10X_P4_3 10X_P4_4 10X_P7_7
  0       52      398       71
  1       31      461        0
  2       36      280      175
  3        3      398       19
  4       18      171       67
  5        2        0      188
  6        4       49       20
  7        3       26       28
# Subset data based on cluster id
subtiss <- SubsetData(object = tiss, ident.use = c(3), do.center = F, do.scale = F, cells.use = )

# To subset data based on annotation or other metadata, you can explicitly pass cell names

cells.to.use = tiss@cell.names[which(tiss@meta.data$mouse.sex == 'F')]
subtiss <- SubsetData(object = tiss, cells.use = cells.to.use, do.center = F, do.scale = F)

Save the Robject for later

When you save the annotated tissue, please give it a name.

filename = here('00_data_ingest', '04_tissue_robj_generated', 
                    paste0("droplet", tissue_of_interest, "_seurat_tiss.Robj"))
print(filename)
[1] "/Users/Aaron/Documents/GitHub/tabula-muris/00_data_ingest/04_tissue_robj_generated/dropletBladder_seurat_tiss.Robj"
save(tiss, file=filename)

Export the final metadata

So that Biohub can easily combine all your cell_ontology_classs, please export them as a simple csv.

head(tiss@meta.data)
filename = here('00_data_ingest', '03_tissue_cell_ontology_class_csv', 
                    paste0(tissue_of_interest, "_droplet_cell_ontology_class.csv"))
write.csv(tiss@meta.data[,c('channel','cell_ontology_class','cell_ontology_id')], file=filename)
cannot open file '/Users/Aaron/Documents/GitHub/tabula-muris/00_data_ingest/03_tissue_cell_ontology_class_csv/Bladder_droplet_cell_ontology_class.csv': No such file or directoryError in file(file, ifelse(append, "a", "w")) : 
  cannot open the connection

no analysis completed below

Subset and iterate

We can repeat the above analysis on a subset of cells, defined using cluster IDs or some other metadata. This is a good way to drill down and find substructure.

First subset

# If this fails for your subset, it may be that cells.use is more cells than you have left! Try reducing it.
PCHeatmap(object = subtiss, pc.use = 1:3, cells.use = 250, do.balanced = TRUE, label.columns = FALSE, num.genes = 12)

subtiss <- NormalizeData(object = subtiss)
subtiss <- ScaleData(object = subtiss, vars.to.regress = c("nUMI", "percent.ribo","Rn45s"))

Run Principal Component Analysis.

# Set number of principal components. 
sub.n.pcs = 5
# If this fails for your subset, it may be that cells.use is more cells than you have left! Try reducing it.
PCHeatmap(object = subtiss, pc.use = 1:3, cells.use = 250, do.balanced = TRUE, label.columns = FALSE, num.genes = 12)

Later on (in FindClusters and TSNE) you will pick a number of principal components to use. This has the effect of keeping the major directions of variation in the data and, ideally, supressing noise. There is no correct answer to the number to use, but a decent rule of thumb is to go until the plot plateaus.

Choose the number of principal components to use.

# If cells are too spread out, you can raise the perplexity. If you have few cells, try a lower perplexity (but never less than 10).
subtiss <- RunTSNE(object = subtiss, dims.use = 1:sub.n.pcs, seed.use = 10, perplexity=20)

The clustering is performed based on a nearest neighbors graph. Cells that have similar expression will be joined together. The Louvain algorithm looks for groups of cells with high modularity–more connections within the group than between groups. The resolution parameter determines the scale…higher resolution will give more clusters, lower resolution will give fewer.

# Set resolution 
sub.res.used <- 1

subtiss <- FindClusters(object = subtiss, reduction.type = "pca", dims.use = 1:sub.n.pcs, 
    resolution = sub.res.used, ,print.output = 0, save.SNN = TRUE)

To visualize

# If cells are too spread out, you can raise the perplexity. If you have few cells, try a lower perplexity (but never less than 10).
subtiss <- RunTSNE(object = subtiss, dims.use = 1:sub.n.pcs, seed.use = 10, perplexity=20)
# note that you can set do.label=T to help label individual clusters
TSNEPlot(object = subtiss, do.label = T)
# To change the y-axis to show raw counts, add use.raw = T.
DotPlot(subtiss, genes_to_check, plot.legend = T)

subtiss.markers %>% group_by(cluster) %>% top_n(6, avg_diff)

Check expression of genes of interset.

genes_to_check = c('Alb', 'Cyp2f2', 'Cyp2e1', 'Hamp', 'Glul', 'Ass1', 'Axin2', 'Igfbp2')

FeaturePlot(subtiss, genes_to_check, pt.size = 1)

Dotplots let you see the intensity of exppression and the fraction of cells expressing for each of your genes of interest.

table(as.character(subtiss@ident), as.character(subtiss@meta.data$channel))
   
    10X_P7_7
  0      167
  1      117
  2       93
  3       74
  4       69
  5       35
  6       13

How big are the clusters?

table(subtiss@ident)

Checking for batch effects

Color by metadata, like plate barcode, to check for batch effects.

TSNEPlot(object = subtiss, do.return = TRUE, group.by = "channel")

Print a table showing the count of cells in each identity category from each plate.

Save the Robject for later

When you save the annotated tissue, please give it a name.

filename = here('00_data_ingest', '04_tissue_robj_generated', 
                    paste0("droplet", tissue_of_interest, "_seurat_tiss.Robj"))
print(filename)
save(tiss, file=filename)
# To reload a saved object
# filename = here('00_data_ingest', '04_tissue_robj_generated', 
#                      paste0("facs", tissue_of_interest, "_seurat_tiss.Robj"))
# load(file=filename)

Export the final metadata

So that Biohub can easily combine all your cell_ontology_classs, please export them as a simple csv.

head(tiss@meta.data)
filename = here('00_data_ingest', '03_tissue_cell_ontology_class_csv', 
                    paste0(tissue_of_interest, "_droplet_cell_ontology_class.csv"))
write.csv(tiss@meta.data[,c('channel','cell_ontology_class','cell_ontology_id')], file=filename)
LS0tCiB0aXRsZTogIkJsYWRkZXIgRHJvcGxldCBOb3RlYm9vayIKIG91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCkVudGVyIHRoZSBkaXJlY3Rvcnkgb2YgdGhlIG1hY2EgZm9sZGVyIG9uIHlvdXIgZHJpdmUgYW5kIHRoZSBuYW1lIG9mIHRoZSB0aXNzdWUgeW91IHdhbnQgdG8gYW5hbHl6ZS4KCmBgYHtyfQp0aXNzdWVfb2ZfaW50ZXJlc3QgPSAiQmxhZGRlciIKYGBgCgpMb2FkIHRoZSByZXF1aXNpdGUgcGFja2FnZXMgYW5kIHNvbWUgYWRkaXRpb25hbCBoZWxwZXIgZnVuY3Rpb25zLgoKYGBge3J9CmxpYnJhcnkoaGVyZSkKbGlicmFyeSh1c2VmdWwpCmxpYnJhcnkoU2V1cmF0KQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KE1hdHJpeCkKbGlicmFyeShvbnRvbG9neUluZGV4KQpjZWxsX29udG9sb2d5ID0gZ2V0X29udG9sb2d5KCdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vb2JvcGhlbm90eXBlL2NlbGwtb250b2xvZ3kvbWFzdGVyL2NsLWJhc2ljLm9ibycsIGV4dHJhY3RfdGFncz0nZXZlcnl0aGluZycpCgp2YWxpZGF0ZV9jZWxsX29udG9sb2d5ID0gZnVuY3Rpb24oY2VsbF9vbnRvbG9neV9jbGFzcyl7CiAgaW5fY2VsbF9vbnRvbG9neSA9IHNhcHBseShjZWxsX29udG9sb2d5X2NsYXNzLCBmdW5jdGlvbih4KSBpcy5lbGVtZW50KHgsIGNlbGxfb250b2xvZ3kkbmFtZSkpCiAgaWYgKCFhbGwoaW5fY2VsbF9vbnRvbG9neSkpIHsKICAgIG1lc3NhZ2UgPSBwYXN0ZTAoJyInLCBjZWxsX29udG9sb2d5X2NsYXNzWyFpbl9jZWxsX29udG9sb2d5XSwgJyIgaXMgbm90IGluIHRoZSBjZWxsIG9udG9sb2d5CicpCiAgICBzdG9wKG1lc3NhZ2UpCiAgfQp9CmNvbnZlcnRfdG9fY2VsbF9vbnRvbG9neV9pZCA9IGZ1bmN0aW9uKGNlbGxfb250b2xvZ3lfY2xhc3MpewogIHJldHVybihzYXBwbHkoY2VsbF9vbnRvbG9neV9jbGFzcywgZnVuY3Rpb24oeCkgYXMudmVjdG9yKGNlbGxfb250b2xvZ3kkaWRbY2VsbF9vbnRvbG9neSRuYW1lID09IHhdKVsxXSkpCn0Kc2F2ZV9kaXIgPSBoZXJlKCcwMF9kYXRhX2luZ2VzdCcsICcwNF90aXNzdWVfcm9ial9nZW5lcmF0ZWQnKQpgYGAKCgoKYGBge3J9CiMgcmVhZCB0aGUgbWV0YWRhdGEgdG8gZ2V0IHRoZSBwbGF0ZXMgd2Ugd2FudApkcm9wbGV0X21ldGFkYXRhX2ZpbGVuYW1lID0gaGVyZSgnMDBfZGF0YV9pbmdlc3QnLCAnMDFfZHJvcGxldF9yYXdfZGF0YScsICdtZXRhZGF0YV9kcm9wbGV0LmNzdicpCgpkcm9wbGV0X21ldGFkYXRhIDwtIHJlYWQuY3N2KGRyb3BsZXRfbWV0YWRhdGFfZmlsZW5hbWUsIHNlcD0iLCIsIGhlYWRlciA9IFRSVUUpCmNvbG5hbWVzKGRyb3BsZXRfbWV0YWRhdGEpWzFdIDwtICJjaGFubmVsIgpkcm9wbGV0X21ldGFkYXRhCmBgYAoKU3Vic2V0IHRoZSBtZXRhZGF0YSBvbiB0aGUgdGlzc3VlLgoKYGBge3J9CnRpc3N1ZV9tZXRhZGF0YSA9IGZpbHRlcihkcm9wbGV0X21ldGFkYXRhLCB0aXNzdWUgPT0gdGlzc3VlX29mX2ludGVyZXN0KVssYygnY2hhbm5lbCcsJ3Rpc3N1ZScsJ3N1YnRpc3N1ZScsJ21vdXNlLnNleCcsICdtb3VzZS5pZCcpXQp0aXNzdWVfbWV0YWRhdGEKYGBgCgoKVXNlIG9ubHkgdGhlIG1ldGFkYXRhIHJvd3MgY29ycmVzcG9uZGluZyB0byBCbGFkZGVyIHBsYXRlcy4gTWFrZSBhIHBsYXRlIGJhcmNvZGUgZGF0YWZyYW1lIHRvICJleHBhbmQiIHRoZSBwZXItcGxhdGUgbWV0YWRhdGEgdG8gYmUgcGVyLWNlbGwuCgpgYGB7cn0KIyBMb2FkIHRoZSBnZW5lIG5hbWVzIGFuZCBzZXQgdGhlIG1ldGFkYXRhIGNvbHVtbnMgYnkgb3BlbmluZyB0aGUgZmlyc3QgZmlsZQoKc3ViZm9sZGVyID0gcGFzdGUwKHRpc3N1ZV9vZl9pbnRlcmVzdCwgJy0nLCB0aXNzdWVfbWV0YWRhdGEkY2hhbm5lbFsxXSkKcmF3LmRhdGEgPC0gUmVhZDEwWChkYXRhLmRpciA9IGhlcmUoJzAwX2RhdGFfaW5nZXN0JywgJzAxX2Ryb3BsZXRfcmF3X2RhdGEnLCAnZHJvcGxldCcsIHN1YmZvbGRlcikpCmNvbG5hbWVzKHJhdy5kYXRhKSA8LSBsYXBwbHkoY29sbmFtZXMocmF3LmRhdGEpLCBmdW5jdGlvbih4KSBwYXN0ZTAodGlzc3VlX21ldGFkYXRhJGNoYW5uZWxbMV0sICdfJywgeCkpCm1ldGEuZGF0YSA9IGRhdGEuZnJhbWUocm93Lm5hbWVzID0gY29sbmFtZXMocmF3LmRhdGEpKQptZXRhLmRhdGFbJ2NoYW5uZWwnXSA9IHRpc3N1ZV9tZXRhZGF0YSRjaGFubmVsWzFdCgppZiAobGVuZ3RoKHRpc3N1ZV9tZXRhZGF0YSRjaGFubmVsKSA+IDEpewogICMgU29tZSB0aXNzdWVzLCBsaWtlIFRoeW11cyBhbmQgSGVhcnQgaGFkIG9ubHkgb25lIGNoYW5uZWwKICBmb3IoaSBpbiAyOm5yb3codGlzc3VlX21ldGFkYXRhKSl7CiAgICBzdWJmb2xkZXIgPSBwYXN0ZTAodGlzc3VlX29mX2ludGVyZXN0LCAnLScsIHRpc3N1ZV9tZXRhZGF0YSRjaGFubmVsW2ldKQogICAgbmV3LmRhdGEgPC0gUmVhZDEwWChkYXRhLmRpciA9IGhlcmUoJzAwX2RhdGFfaW5nZXN0JywgJzAxX2Ryb3BsZXRfcmF3X2RhdGEnLCAnZHJvcGxldCcsIHN1YmZvbGRlcikpCiAgICBjb2xuYW1lcyhuZXcuZGF0YSkgPC0gbGFwcGx5KGNvbG5hbWVzKG5ldy5kYXRhKSwgZnVuY3Rpb24oeCkgcGFzdGUwKHRpc3N1ZV9tZXRhZGF0YSRjaGFubmVsW2ldLCAnXycsIHgpKQogICAgCiAgICBuZXcubWV0YWRhdGEgPSBkYXRhLmZyYW1lKHJvdy5uYW1lcyA9IGNvbG5hbWVzKG5ldy5kYXRhKSkKICAgIG5ldy5tZXRhZGF0YVsnY2hhbm5lbCddID0gdGlzc3VlX21ldGFkYXRhJGNoYW5uZWxbaV0KICAgIAogICAgcmF3LmRhdGEgPSBjYmluZChyYXcuZGF0YSwgbmV3LmRhdGEpCiAgICBtZXRhLmRhdGEgPSByYmluZChtZXRhLmRhdGEsIG5ldy5tZXRhZGF0YSkKICB9Cn0KCnJuYW1lcyA9IHJvdy5uYW1lcyhtZXRhLmRhdGEpCm1ldGEuZGF0YSA8LSBtZXJnZShtZXRhLmRhdGEsIHRpc3N1ZV9tZXRhZGF0YSwgc29ydCA9IEYpCnJvdy5uYW1lcyhtZXRhLmRhdGEpIDwtIHJuYW1lcwpkaW0ocmF3LmRhdGEpCmNvcm5lcihyYXcuZGF0YSkKaGVhZChtZXRhLmRhdGEpCgpgYGAKClByb2Nlc3MgdGhlIHJhdyBkYXRhIGFuZCBsb2FkIGl0IGludG8gdGhlIFNldXJhdCBvYmplY3QuCgpgYGB7cn0KIyBGaW5kIEVSQ0MncywgY29tcHV0ZSB0aGUgcGVyY2VudCBFUkNDLCBhbmQgZHJvcCB0aGVtIGZyb20gdGhlIHJhdyBkYXRhLgplcmNjcyA8LSBncmVwKHBhdHRlcm4gPSAiXkVSQ0MtIiwgeCA9IHJvd25hbWVzKHggPSByYXcuZGF0YSksIHZhbHVlID0gVFJVRSkKcGVyY2VudC5lcmNjIDwtIE1hdHJpeDo6Y29sU3VtcyhyYXcuZGF0YVtlcmNjcywgXSkvTWF0cml4Ojpjb2xTdW1zKHJhdy5kYXRhKQplcmNjLmluZGV4IDwtIGdyZXAocGF0dGVybiA9ICJeRVJDQy0iLCB4ID0gcm93bmFtZXMoeCA9IHJhdy5kYXRhKSwgdmFsdWUgPSBGQUxTRSkKcmF3LmRhdGEgPC0gcmF3LmRhdGFbLWVyY2MuaW5kZXgsXQoKIyBDcmVhdGUgdGhlIFNldXJhdCBvYmplY3Qgd2l0aCBhbGwgdGhlIGRhdGEKdGlzcyA8LSBDcmVhdGVTZXVyYXRPYmplY3QocmF3LmRhdGEgPSByYXcuZGF0YSwgcHJvamVjdCA9IHRpc3N1ZV9vZl9pbnRlcmVzdCwgCiAgICAgICAgICAgICAgICAgICAgbWluLmNlbGxzID0gNSwgbWluLmdlbmVzID0gNSkKCnRpc3MgPC0gQWRkTWV0YURhdGEob2JqZWN0ID0gdGlzcywgbWV0YS5kYXRhKQp0aXNzIDwtIEFkZE1ldGFEYXRhKG9iamVjdCA9IHRpc3MsIHBlcmNlbnQuZXJjYywgY29sLm5hbWUgPSAicGVyY2VudC5lcmNjIikKCiMgQ3JlYXRlIG1ldGFkYXRhIGNvbHVtbnMgZm9yIGNlbGxfb250b2xvZ3lfY2xhc3NzIGFuZCBzdWJjZWxsX29udG9sb2d5X2NsYXNzcwp0aXNzQG1ldGEuZGF0YVssJ2NlbGxfb250b2xvZ3lfY2xhc3MnXSA8LSBOQQp0aXNzQG1ldGEuZGF0YVssJ3N1YmNlbGxfb250b2xvZ3lfY2xhc3MnXSA8LSBOQQpgYGAKCgpDYWxjdWxhdGUgcGVyY2VudCByaWJvc29tYWwgZ2VuZXMuCgpgYGB7cn0Kcmliby5nZW5lcyA8LSBncmVwKHBhdHRlcm4gPSAiXlJwW3NsXVtbOmRpZ2l0Ol1dIiwgeCA9IHJvd25hbWVzKHggPSB0aXNzQGRhdGEpLCB2YWx1ZSA9IFRSVUUpCnBlcmNlbnQucmlibyA8LSBNYXRyaXg6OmNvbFN1bXModGlzc0ByYXcuZGF0YVtyaWJvLmdlbmVzLCBdKS9NYXRyaXg6OmNvbFN1bXModGlzc0ByYXcuZGF0YSkKdGlzcyA8LSBBZGRNZXRhRGF0YShvYmplY3QgPSB0aXNzLCBtZXRhZGF0YSA9IHBlcmNlbnQucmlibywgY29sLm5hbWUgPSAicGVyY2VudC5yaWJvIikKYGBgCgpBIHNhbml0eSBjaGVjazogZ2VuZXMgcGVyIGNlbGwgdnMgcmVhZHMgcGVyIGNlbGwuCgpgYGB7cn0KR2VuZVBsb3Qob2JqZWN0ID0gdGlzcywgZ2VuZTEgPSAiblVNSSIsIGdlbmUyID0gIm5HZW5lIiwgdXNlLnJhdz1UKQpgYGAKCkZpbHRlciBvdXQgY2VsbHMgd2l0aCBmZXcgcmVhZHMgYW5kIGZldyBnZW5lcy4KCmBgYHtyfQp0aXNzIDwtIEZpbHRlckNlbGxzKG9iamVjdCA9IHRpc3MsIHN1YnNldC5uYW1lcyA9IGMoIm5HZW5lIiwgIm5VTUkiKSwgCiAgICBsb3cudGhyZXNob2xkcyA9IGMoNTAwLCAxMDAwKSwgaGlnaC50aHJlc2hvbGRzID0gYygyNTAwMCwgNTAwMDAwMCkpCmBgYAoKCk5vcm1hbGl6ZSB0aGUgZGF0YSwgdGhlbiByZWdyZXNzIG91dCBjb3JyZWxhdGlvbiB3aXRoIHRvdGFsIHJlYWRzCmBgYHtyfQp0aXNzIDwtIE5vcm1hbGl6ZURhdGEob2JqZWN0ID0gdGlzcykKdGlzcyA8LSBTY2FsZURhdGEob2JqZWN0ID0gdGlzcykKdGlzcyA8LSBGaW5kVmFyaWFibGVHZW5lcyhvYmplY3QgPSB0aXNzLCBkby5wbG90ID0gVFJVRSwgeC5oaWdoLmN1dG9mZiA9IEluZiwgeS5jdXRvZmYgPSAwLjUpCmBgYAoKClJ1biBQcmluY2lwYWwgQ29tcG9uZW50IEFuYWx5c2lzLgpgYGB7cn0KdGlzcyA8LSBSdW5QQ0Eob2JqZWN0ID0gdGlzcywgZG8ucHJpbnQgPSBGQUxTRSkKdGlzcyA8LSBQcm9qZWN0UENBKG9iamVjdCA9IHRpc3MsIGRvLnByaW50ID0gRkFMU0UpCmBgYAoKYGBge3IsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9NCwgZmlnLndpZHRoPTh9ClBDSGVhdG1hcChvYmplY3QgPSB0aXNzLCBwYy51c2UgPSAxOjMsIGNlbGxzLnVzZSA9IDUwMCwgZG8uYmFsYW5jZWQgPSBUUlVFLCBsYWJlbC5jb2x1bW5zID0gRkFMU0UsIG51bS5nZW5lcyA9IDgpCmBgYAoKTGF0ZXIgb24gKGluIEZpbmRDbHVzdGVycyBhbmQgVFNORSkgeW91IHdpbGwgcGljayBhIG51bWJlciBvZiBwcmluY2lwYWwgY29tcG9uZW50cyB0byB1c2UuIFRoaXMgaGFzIHRoZSBlZmZlY3Qgb2Yga2VlcGluZyB0aGUgbWFqb3IgZGlyZWN0aW9ucyBvZiB2YXJpYXRpb24gaW4gdGhlIGRhdGEgYW5kLCBpZGVhbGx5LCBzdXByZXNzaW5nIG5vaXNlLiBUaGVyZSBpcyBubyBjb3JyZWN0IGFuc3dlciB0byB0aGUgbnVtYmVyIHRvIHVzZSwgYnV0IGEgZGVjZW50IHJ1bGUgb2YgdGh1bWIgaXMgdG8gZ28gdW50aWwgdGhlIHBsb3QgcGxhdGVhdXMuCgpgYGB7cn0KUENFbGJvd1Bsb3Qob2JqZWN0ID0gdGlzcykKYGBgCgpDaG9vc2UgdGhlIG51bWJlciBvZiBwcmluY2lwYWwgY29tcG9uZW50cyB0byB1c2UuCmBgYHtyfQojIFNldCBudW1iZXIgb2YgcHJpbmNpcGFsIGNvbXBvbmVudHMuIApuLnBjcyA9IDEwCmBgYAoKClRoZSBjbHVzdGVyaW5nIGlzIHBlcmZvcm1lZCBiYXNlZCBvbiBhIG5lYXJlc3QgbmVpZ2hib3JzIGdyYXBoLiBDZWxscyB0aGF0IGhhdmUgc2ltaWxhciBleHByZXNzaW9uIHdpbGwgYmUgam9pbmVkIHRvZ2V0aGVyLiBUaGUgTG91dmFpbiBhbGdvcml0aG0gbG9va3MgZm9yIGdyb3VwcyBvZiBjZWxscyB3aXRoIGhpZ2ggbW9kdWxhcml0eS0tbW9yZSBjb25uZWN0aW9ucyB3aXRoaW4gdGhlIGdyb3VwIHRoYW4gYmV0d2VlbiBncm91cHMuIFRoZSByZXNvbHV0aW9uIHBhcmFtZXRlciBkZXRlcm1pbmVzIHRoZSBzY2FsZS4uLmhpZ2hlciByZXNvbHV0aW9uIHdpbGwgZ2l2ZSBtb3JlIGNsdXN0ZXJzLCBsb3dlciByZXNvbHV0aW9uIHdpbGwgZ2l2ZSBmZXdlci4KCkZvciB0aGUgdG9wLWxldmVsIGNsdXN0ZXJpbmcsIGFpbSB0byB1bmRlci1jbHVzdGVyIGluc3RlYWQgb2Ygb3Zlci1jbHVzdGVyLiBJdCB3aWxsIGJlIGVhc3kgdG8gc3Vic2V0IGdyb3VwcyBhbmQgZnVydGhlciBhbmFseXplIHRoZW0gYmVsb3cuCgpgYGB7cn0KIyBTZXQgcmVzb2x1dGlvbiAKcmVzLnVzZWQgPC0gMC40Cgp0aXNzIDwtIEZpbmRDbHVzdGVycyhvYmplY3QgPSB0aXNzLCByZWR1Y3Rpb24udHlwZSA9ICJwY2EiLCBkaW1zLnVzZSA9IDE6bi5wY3MsIAogICAgcmVzb2x1dGlvbiA9IHJlcy51c2VkLCBwcmludC5vdXRwdXQgPSAwLCBzYXZlLlNOTiA9IFRSVUUsIGZvcmNlLnJlY2FsYyA9IFRSVUUpCmBgYAoKClRvIHZpc3VhbGl6ZSAKYGBge3J9CiMgSWYgY2VsbHMgYXJlIHRvbyBzcHJlYWQgb3V0LCB5b3UgY2FuIHJhaXNlIHRoZSBwZXJwbGV4aXR5LiBJZiB5b3UgaGF2ZSBmZXcgY2VsbHMsIHRyeSBhIGxvd2VyIHBlcnBsZXhpdHkgKGJ1dCBuZXZlciBsZXNzIHRoYW4gMTApLgp0aXNzIDwtIFJ1blRTTkUob2JqZWN0ID0gdGlzcywgZGltcy51c2UgPSAxOm4ucGNzLCBzZWVkLnVzZSA9IDEwLCBwZXJwbGV4aXR5PTMwLCBkaW0uZW1iZWQgPSAyKQpgYGAKCmBgYHtyfQojIG5vdGUgdGhhdCB5b3UgY2FuIHNldCBkby5sYWJlbD1UIHRvIGhlbHAgbGFiZWwgaW5kaXZpZHVhbCBjbHVzdGVycwpUU05FUGxvdChvYmplY3QgPSB0aXNzLCBkby5sYWJlbCA9IFQpCmBgYAoKQ2hlY2sgZXhwcmVzc2lvbiBvZiBnZW5lcyBvZiBpbnRlcnNldC4KCmBgYHtyLCBlY2hvPUZBTFNFLCBmaWcuaGVpZ2h0PTEyLCBmaWcud2lkdGg9OH0KZ2VuZXNfdG9fY2hlY2sgPSBjKCdFcGNhbScsJ1VwazFiJywgJ1VwazNhJywnR3JobDMnLCAnS3J0NScsICdLcnQxNCcsICdEY24nLCAnQ29sMWExJywnUHRjaDEnLCAnSGhpcCcsICdQZWNhbTEnLCAnQ2QxNCcsICdTY2FyYTUnLCAnQ2FyMycpCiNnZW5lc190b19jaGVjayA9IGMoJ0FsYicsICdDeXAyZjInLCAnQ3lwMiwgJ0tydDIwJykKCkZlYXR1cmVQbG90KHRpc3MsIGdlbmVzX3RvX2NoZWNrLCBwdC5zaXplID0gMSwgbkNvbCA9IDMpCmBgYAoKYGBge3J9ClZsblBsb3QodGlzcywgZ2VuZXNfdG9fY2hlY2spCmBgYAoKCkRvdHBsb3RzIGxldCB5b3Ugc2VlIHRoZSBpbnRlbnNpdHkgb2YgZXhwcHJlc3Npb24gYW5kIHRoZSBmcmFjdGlvbiBvZiBjZWxscyBleHByZXNzaW5nIGZvciBlYWNoIG9mIHlvdXIgZ2VuZXMgb2YgaW50ZXJlc3QuCgpgYGB7ciwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9OH0KIyBUbyBjaGFuZ2UgdGhlIHktYXhpcyB0byBzaG93IHJhdyBjb3VudHMsIGFkZCB1c2UucmF3ID0gVC4KRG90UGxvdCh0aXNzLCBnZW5lc190b19jaGVjaywgcGxvdC5sZWdlbmQgPSBUKQpgYGAKCkhvdyBiaWcgYXJlIHRoZSBjbHVzdGVycz8KYGBge3J9CnRhYmxlKHRpc3NAaWRlbnQpCmBgYAoKCldoaWNoIG1hcmtlcnMgaWRlbnRpZnkgYSBzcGVjaWZpYyBjbHVzdGVyPwoKYGBge3J9CmNsdXN0Lm1hcmtlcnMgPC0gRmluZE1hcmtlcnMob2JqZWN0ID0gdGlzcywgaWRlbnQuMSA9IDIsIGlkZW50LjIgPSAxLCBvbmx5LnBvcyA9IFRSVUUsIG1pbi5wY3QgPSAwLjI1LCB0aHJlc2gudXNlID0gMC4yNSkKYGBgCgoKYGBge3J9CnByaW50KHggPSBoZWFkKHg9IGNsdXN0Lm1hcmtlcnMsIG4gPSAxMCkpCmBgYAoKWW91IGNhbiBhbHNvIGNvbXB1dGUgYWxsIG1hcmtlcnMgZm9yIGFsbCBjbHVzdGVycyBhdCBvbmNlLiBUaGlzIG1heSB0YWtlIHNvbWUgdGltZS4KYGBge3J9CnRpc3MubWFya2VycyA8LSBGaW5kQWxsTWFya2VycyhvYmplY3QgPSB0aXNzLCBvbmx5LnBvcyA9IFRSVUUsIG1pbi5wY3QgPSAwLjI1LCB0aHJlc2gudXNlID0gMC4yNSkKYGBgCgpgYGB7cn0Kc2F2ZS5pbWFnZSgiYmxhZGRlcl9kcm9wbGV0X2ltYWdlLlJEYXRhIikKYGBgCgoKRGlzcGxheSB0aGUgdG9wIG1hcmtlcnMgeW91IGNvbXB1dGVkIGFib3ZlLgpgYGB7cn0KdGlzcy5tYXJrZXJzICU+JSBncm91cF9ieShjbHVzdGVyKSAlPiUgdG9wX24oMjAsIGF2Z19sb2dGQykKYGBgCgpgYGB7ciwgZWNobz1GQUxTRSwgZmlnLmhlaWdodD00LCBmaWcud2lkdGg9OH0KIyBUbyBjaGFuZ2UgdGhlIHktYXhpcyB0byBzaG93IHJhdyBjb3VudHMsIGFkZCB1c2UucmF3ID0gVC4KRG90UGxvdCh0aXNzLCBnZW5lc190b19jaGVjaywgcGxvdC5sZWdlbmQgPSBUKQpgYGAKCmBgYHtyfQp0aXNzPSBCdWlsZENsdXN0ZXJUcmVlKHRpc3MpCmBgYAoKYGBge3J9Ck5vZGUxMV9tYXJrZXJzID0gRmluZEFsbE1hcmtlcnNOb2RlKHRpc3MsIG5vZGUgPSAxMSkKYGBgCgpgYGB7cn0KTm9kZTExX21hcmtlcnMgJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSB0b3BfbigzMCwgYXZnX2xvZ0ZDKQpgYGAKCgojIyBBc3NpZ25pbmcgY2VsbCB0eXBlIGlkZW50aXR5IHRvIGNsdXN0ZXJzCgpBdCBhIGNvYXJzZSBsZXZlbCwgd2UgY2FuIHVzZSBjYW5vbmljYWwgbWFya2VycyB0byBtYXRjaCB0aGUgdW5iaWFzZWQgY2x1c3RlcmluZyB0byBrbm93biBjZWxsIHR5cGVzOgoKCmBgYHtyfQojIHN0YXNoIGN1cnJlbnQgY2x1c3RlciBJRHMKdGlzcyA8LSBTdGFzaElkZW50KG9iamVjdCA9IHRpc3MsIHNhdmUubmFtZSA9ICJjbHVzdGVyLmlkcyIpCgojIGVudW1lcmF0ZSBjdXJyZW50IGNsdXN0ZXIgSURzIGFuZCB0aGUgbGFiZWxzIGZvciB0aGVtCmNsdXN0ZXIuaWRzIDwtIGMoMCwgMSwgMiwgMywgNCwgNSwgNiwgNykKZnJlZS5jZWxsX29udG9sb2d5X2NsYXNzIDwtIGMoIkJsYWRkZXIgbWVzZW5jaHltYWwgY2VsbCIsICJCbGFkZGVyIG1lc2VuY2h5bWFsIGNlbGwiLCAiQmFzYWwgYmxhZGRlciBlcGl0aGVsaWFsIGNlbGwiLCAiTHVtaW5hbCBibGFkZGVyIGVwaXRoZWxpYWwgY2VsbCIsICJMdW1pbmFsIGJsYWRkZXIgZXBpdGhlbGlhbCBjZWxsIiwgIkJsYWRkZXIgbWVzZW5jaHltYWwgY2VsbCIsICJNb25vY3l0ZS9NYWNyb3BoYWdlIiwgIkVuZG90aGVsaWFsIGNlbGwiKQoKY2VsbF9vbnRvbG9neV9jbGFzcyA8LSBjKCJibGFkZGVyIGNlbGwiLCAiYmxhZGRlciBjZWxsIiAsICJibGFkZGVyIHVyb3RoZWxpYWwgY2VsbCIsICJibGFkZGVyIHVyb3RoZWxpYWwgY2VsbCIsICJibGFkZGVyIHVyb3RoZWxpYWwgY2VsbCIsICJibGFkZGVyIGNlbGwiLCAibGV1a29jeXRlIiwgImVuZG90aGVsaWFsIGNlbGwiKQppbl9jZWxsX29udG9sb2d5ID0gc2FwcGx5KGNlbGxfb250b2xvZ3lfY2xhc3MsIGZ1bmN0aW9uKHgpIGlzLmVsZW1lbnQoeCwgY2VsbF9vbnRvbG9neSRuYW1lKSkKaWYgKCFhbGwoaW5fY2VsbF9vbnRvbG9neSkpIHsKICBtZXNzYWdlID0gcGFzdGUwKCciJywgY2VsbF9vbnRvbG9neV9jbGFzc1shaW5fY2VsbF9vbnRvbG9neV0sICciIGlzIG5vdCBpbiB0aGUgY2VsbCBvbnRvbG9neVxuJykKICBzdG9wKG1lc3NhZ2UpCn0KY2VsbF9vbnRvbG9neV9pZCA8LSBjKCJDTDoxMDAxMzE5IiwgIkNMOjEwMDEzMTkiICwgIkNMXzEwMDE0MjgiLCAiQ0xfMTAwMTQyOCIsICJDTF8xMDAxNDI4IiwgIkNMOjEwMDEzMTkiLCAiQ0xfMDAwMDczOCIsICJDTF8wMDAwMTE1IikKCnRpc3NAbWV0YS5kYXRhWywnY2VsbF9vbnRvbG9neV9jbGFzcyddIDwtIHBseXI6Om1hcHZhbHVlcyh4ID0gdGlzc0BpZGVudCwgZnJvbSA9IGNsdXN0ZXIuaWRzLCB0byA9IGNlbGxfb250b2xvZ3lfY2xhc3MpCnRpc3NAbWV0YS5kYXRhWywnY2VsbF9vbnRvbG9neV9pZCddIDwtIHBseXI6Om1hcHZhbHVlcyh4ID0gdGlzc0BpZGVudCwgZnJvbSA9IGNsdXN0ZXIuaWRzLCB0byA9IGNlbGxfb250b2xvZ3lfaWQpCgp0aXNzQG1ldGEuZGF0YVt0aXNzQGNlbGwubmFtZXMsJ2NlbGxfb250b2xvZ3lfY2xhc3MnXSA8LSBhcy5jaGFyYWN0ZXIodGlzc0BtZXRhLmRhdGEkY2VsbF9vbnRvbG9neV9jbGFzcykKdGlzc0BtZXRhLmRhdGFbdGlzc0BjZWxsLm5hbWVzLCdjZWxsX29udG9sb2d5X2lkJ10gPC0gYXMuY2hhcmFjdGVyKHRpc3NAbWV0YS5kYXRhJGNlbGxfb250b2xvZ3lfaWQpCgpUU05FUGxvdChvYmplY3QgPSB0aXNzLCBkby5sYWJlbCA9IFRSVUUsIHB0LnNpemUgPSAwLjUsIGdyb3VwLmJ5PSdjZWxsX29udG9sb2d5X2NsYXNzJykKYGBgCgoKIyMgQ2hlY2tpbmcgZm9yIGJhdGNoIGVmZmVjdHMKCgpDb2xvciBieSBtZXRhZGF0YSwgbGlrZSBwbGF0ZSBiYXJjb2RlLCB0byBjaGVjayBmb3IgYmF0Y2ggZWZmZWN0cy4KYGBge3J9ClRTTkVQbG90KG9iamVjdCA9IHRpc3MsIGRvLnJldHVybiA9IFRSVUUsIGdyb3VwLmJ5ID0gImNoYW5uZWwiKQpgYGAKCmBgYHtyfQpUU05FUGxvdChvYmplY3QgPSB0aXNzLCBkby5yZXR1cm4gPSBUUlVFLCBncm91cC5ieSA9ICJtb3VzZS5zZXgiKQpgYGAKClByaW50IGEgdGFibGUgc2hvd2luZyB0aGUgY291bnQgb2YgY2VsbHMgaW4gZWFjaCBpZGVudGl0eSBjYXRlZ29yeSBmcm9tIGVhY2ggcGxhdGUuCgpgYGB7cn0KdGFibGUoYXMuY2hhcmFjdGVyKHRpc3NAaWRlbnQpLCBhcy5jaGFyYWN0ZXIodGlzc0BtZXRhLmRhdGEkY2hhbm5lbCkpCmBgYAoKYGBge3J9CnRhYmxlKGFzLmNoYXJhY3Rlcih0aXNzQGlkZW50KSwgYXMuY2hhcmFjdGVyKHRpc3NAbWV0YS5kYXRhJG1vdXNlLmlkKSkKYGBgCgojIFNhdmUgdGhlIFJvYmplY3QgZm9yIGxhdGVyCldoZW4geW91IHNhdmUgdGhlIGFubm90YXRlZCB0aXNzdWUsIHBsZWFzZSBnaXZlIGl0IGEgbmFtZS4KCmBgYHtyfQpmaWxlbmFtZSA9IGhlcmUoJzAwX2RhdGFfaW5nZXN0JywgJzA0X3Rpc3N1ZV9yb2JqX2dlbmVyYXRlZCcsIAogICAgICAgICAgICAgICAgICAgIHBhc3RlMCgiZHJvcGxldCIsIHRpc3N1ZV9vZl9pbnRlcmVzdCwgIl9zZXVyYXRfdGlzcy5Sb2JqIikpCnByaW50KGZpbGVuYW1lKQpzYXZlKHRpc3MsIGZpbGU9ZmlsZW5hbWUpCmBgYAoKIyBFeHBvcnQgdGhlIGZpbmFsIG1ldGFkYXRhCgpTbyB0aGF0IEJpb2h1YiBjYW4gZWFzaWx5IGNvbWJpbmUgYWxsIHlvdXIgY2VsbF9vbnRvbG9neV9jbGFzc3MsIHBsZWFzZSBleHBvcnQgdGhlbSBhcyBhIHNpbXBsZSBjc3YuCgpgYGB7cn0KaGVhZCh0aXNzQG1ldGEuZGF0YSkKYGBgCgoKYGBge3J9CmZpbGVuYW1lID0gaGVyZSgnMDBfZGF0YV9pbmdlc3QnLCAnMDNfdGlzc3VlX2NlbGxfb250b2xvZ3lfY2xhc3NfY3N2JywgCiAgICAgICAgICAgICAgICAgICAgcGFzdGUwKHRpc3N1ZV9vZl9pbnRlcmVzdCwgIl9kcm9wbGV0X2NlbGxfb250b2xvZ3lfY2xhc3MuY3N2IikpCgp3cml0ZS5jc3YodGlzc0BtZXRhLmRhdGFbLGMoJ2NoYW5uZWwnLCdjZWxsX29udG9sb2d5X2NsYXNzJywnY2VsbF9vbnRvbG9neV9pZCcpXSwgZmlsZT0iQmxhZGRlcl9kcm9wbGV0X2NlbGxfb250b2xvZ3lfY2xhc3MuY3N2IikKYGBgCgoKCiMjIyMjIyMjIyMjI25vIGFuYWx5c2lzIGNvbXBsZXRlZCBiZWxvdwojIFN1YnNldCBhbmQgaXRlcmF0ZQoKV2UgY2FuIHJlcGVhdCB0aGUgYWJvdmUgYW5hbHlzaXMgb24gYSBzdWJzZXQgb2YgY2VsbHMsIGRlZmluZWQgdXNpbmcgY2x1c3RlciBJRHMgb3Igc29tZSBvdGhlciBtZXRhZGF0YS4gVGhpcyBpcyBhIGdvb2Qgd2F5IHRvIGRyaWxsIGRvd24gYW5kIGZpbmQgc3Vic3RydWN0dXJlLgoKIyMgRmlyc3Qgc3Vic2V0CgpgYGB7cn0KIyBTdWJzZXQgZGF0YSBiYXNlZCBvbiBjbHVzdGVyIGlkCnN1YnRpc3MgPC0gU3Vic2V0RGF0YShvYmplY3QgPSB0aXNzLCBpZGVudC51c2UgPSBjKDMpLCBkby5jZW50ZXIgPSBGLCBkby5zY2FsZSA9IEYsIGNlbGxzLnVzZSA9ICkKCiMgVG8gc3Vic2V0IGRhdGEgYmFzZWQgb24gY2VsbF9vbnRvbG9neV9jbGFzcyBvciBvdGhlciBtZXRhZGF0YSwgeW91IGNhbiBleHBsaWNpdGx5IHBhc3MgY2VsbCBuYW1lcwoKY2VsbHMudG8udXNlID0gdGlzc0BjZWxsLm5hbWVzW3doaWNoKHRpc3NAbWV0YS5kYXRhJG1vdXNlLnNleCA9PSAnRicpXQpzdWJ0aXNzIDwtIFN1YnNldERhdGEob2JqZWN0ID0gdGlzcywgY2VsbHMudXNlID0gY2VsbHMudG8udXNlLCBkby5jZW50ZXIgPSBGLCBkby5zY2FsZSA9IEYpCmBgYAoKYGBge3J9CnN1YnRpc3MgPC0gTm9ybWFsaXplRGF0YShvYmplY3QgPSBzdWJ0aXNzKQpzdWJ0aXNzIDwtIFNjYWxlRGF0YShvYmplY3QgPSBzdWJ0aXNzLCB2YXJzLnRvLnJlZ3Jlc3MgPSBjKCJuVU1JIiwgInBlcmNlbnQucmlibyIsIlJuNDVzIikpCmBgYAoKUnVuIFByaW5jaXBhbCBDb21wb25lbnQgQW5hbHlzaXMuCgpgYGB7cn0Kc3VidGlzcyA8LSBGaW5kVmFyaWFibGVHZW5lcyhvYmplY3QgPSBzdWJ0aXNzLCBkby5wbG90ID0gVFJVRSwgeC5oaWdoLmN1dG9mZiA9IEluZiwgeS5jdXRvZmYgPSAwLjgpCnN1YnRpc3MgPC0gUnVuUENBKG9iamVjdCA9IHN1YnRpc3MsIHBjcy5jb21wdXRlID0gMjAsIHdlaWdodC5ieS52YXIgPSBGKQpzdWJ0aXNzIDwtIFByb2plY3RQQ0Eob2JqZWN0ID0gc3VidGlzcywgZG8ucHJpbnQgPSBGQUxTRSkKYGBgCgpgYGB7cn0KIyBJZiB0aGlzIGZhaWxzIGZvciB5b3VyIHN1YnNldCwgaXQgbWF5IGJlIHRoYXQgY2VsbHMudXNlIGlzIG1vcmUgY2VsbHMgdGhhbiB5b3UgaGF2ZSBsZWZ0ISBUcnkgcmVkdWNpbmcgaXQuClBDSGVhdG1hcChvYmplY3QgPSBzdWJ0aXNzLCBwYy51c2UgPSAxOjMsIGNlbGxzLnVzZSA9IDI1MCwgZG8uYmFsYW5jZWQgPSBUUlVFLCBsYWJlbC5jb2x1bW5zID0gRkFMU0UsIG51bS5nZW5lcyA9IDEyKQpgYGAKCkxhdGVyIG9uIChpbiBGaW5kQ2x1c3RlcnMgYW5kIFRTTkUpIHlvdSB3aWxsIHBpY2sgYSBudW1iZXIgb2YgcHJpbmNpcGFsIGNvbXBvbmVudHMgdG8gdXNlLiBUaGlzIGhhcyB0aGUgZWZmZWN0IG9mIGtlZXBpbmcgdGhlIG1ham9yIGRpcmVjdGlvbnMgb2YgdmFyaWF0aW9uIGluIHRoZSBkYXRhIGFuZCwgaWRlYWxseSwgc3VwcmVzc2luZyBub2lzZS4gVGhlcmUgaXMgbm8gY29ycmVjdCBhbnN3ZXIgdG8gdGhlIG51bWJlciB0byB1c2UsIGJ1dCBhIGRlY2VudCBydWxlIG9mIHRodW1iIGlzIHRvIGdvIHVudGlsIHRoZSBwbG90IHBsYXRlYXVzLgoKYGBge3J9ClBDRWxib3dQbG90KG9iamVjdCA9IHN1YnRpc3MpCmBgYAoKQ2hvb3NlIHRoZSBudW1iZXIgb2YgcHJpbmNpcGFsIGNvbXBvbmVudHMgdG8gdXNlLgpgYGB7cn0KIyBTZXQgbnVtYmVyIG9mIHByaW5jaXBhbCBjb21wb25lbnRzLiAKc3ViLm4ucGNzID0gNQpgYGAKCgpUaGUgY2x1c3RlcmluZyBpcyBwZXJmb3JtZWQgYmFzZWQgb24gYSBuZWFyZXN0IG5laWdoYm9ycyBncmFwaC4gQ2VsbHMgdGhhdCBoYXZlIHNpbWlsYXIgZXhwcmVzc2lvbiB3aWxsIGJlIGpvaW5lZCB0b2dldGhlci4gVGhlIExvdXZhaW4gYWxnb3JpdGhtIGxvb2tzIGZvciBncm91cHMgb2YgY2VsbHMgd2l0aCBoaWdoIG1vZHVsYXJpdHktLW1vcmUgY29ubmVjdGlvbnMgd2l0aGluIHRoZSBncm91cCB0aGFuIGJldHdlZW4gZ3JvdXBzLiBUaGUgcmVzb2x1dGlvbiBwYXJhbWV0ZXIgZGV0ZXJtaW5lcyB0aGUgc2NhbGUuLi5oaWdoZXIgcmVzb2x1dGlvbiB3aWxsIGdpdmUgbW9yZSBjbHVzdGVycywgbG93ZXIgcmVzb2x1dGlvbiB3aWxsIGdpdmUgZmV3ZXIuCgpgYGB7cn0KIyBTZXQgcmVzb2x1dGlvbiAKc3ViLnJlcy51c2VkIDwtIDEKCnN1YnRpc3MgPC0gRmluZENsdXN0ZXJzKG9iamVjdCA9IHN1YnRpc3MsIHJlZHVjdGlvbi50eXBlID0gInBjYSIsIGRpbXMudXNlID0gMTpzdWIubi5wY3MsIAogICAgcmVzb2x1dGlvbiA9IHN1Yi5yZXMudXNlZCwgLHByaW50Lm91dHB1dCA9IDAsIHNhdmUuU05OID0gVFJVRSkKYGBgCgpUbyB2aXN1YWxpemUgCmBgYHtyfQojIElmIGNlbGxzIGFyZSB0b28gc3ByZWFkIG91dCwgeW91IGNhbiByYWlzZSB0aGUgcGVycGxleGl0eS4gSWYgeW91IGhhdmUgZmV3IGNlbGxzLCB0cnkgYSBsb3dlciBwZXJwbGV4aXR5IChidXQgbmV2ZXIgbGVzcyB0aGFuIDEwKS4Kc3VidGlzcyA8LSBSdW5UU05FKG9iamVjdCA9IHN1YnRpc3MsIGRpbXMudXNlID0gMTpzdWIubi5wY3MsIHNlZWQudXNlID0gMTAsIHBlcnBsZXhpdHk9MjApCmBgYAoKYGBge3J9CiMgbm90ZSB0aGF0IHlvdSBjYW4gc2V0IGRvLmxhYmVsPVQgdG8gaGVscCBsYWJlbCBpbmRpdmlkdWFsIGNsdXN0ZXJzClRTTkVQbG90KG9iamVjdCA9IHN1YnRpc3MsIGRvLmxhYmVsID0gVCkKYGBgCgpgYGB7cn0Kc3VidGlzcy5tYXJrZXJzIDwtIEZpbmRBbGxNYXJrZXJzKG9iamVjdCA9IHN1YnRpc3MsIG9ubHkucG9zID0gVFJVRSwgbWluLnBjdCA9IDAuMjUsIHRocmVzaC51c2UgPSAwLjI1KQpgYGAKCmBgYHtyfQpzdWJ0aXNzLm1hcmtlcnMgJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSB0b3Bfbig2LCBhdmdfZGlmZikKYGBgCgpDaGVjayBleHByZXNzaW9uIG9mIGdlbmVzIG9mIGludGVyc2V0LgpgYGB7cn0KZ2VuZXNfdG9fY2hlY2sgPSBjKCdBbGInLCAnQ3lwMmYyJywgJ0N5cDJlMScsICdIYW1wJywgJ0dsdWwnLCAnQXNzMScsICdBeGluMicsICdJZ2ZicDInKQoKRmVhdHVyZVBsb3Qoc3VidGlzcywgZ2VuZXNfdG9fY2hlY2ssIHB0LnNpemUgPSAxKQpgYGAKCkRvdHBsb3RzIGxldCB5b3Ugc2VlIHRoZSBpbnRlbnNpdHkgb2YgZXhwcHJlc3Npb24gYW5kIHRoZSBmcmFjdGlvbiBvZiBjZWxscyBleHByZXNzaW5nIGZvciBlYWNoIG9mIHlvdXIgZ2VuZXMgb2YgaW50ZXJlc3QuCgpgYGB7cn0KIyBUbyBjaGFuZ2UgdGhlIHktYXhpcyB0byBzaG93IHJhdyBjb3VudHMsIGFkZCB1c2UucmF3ID0gVC4KRG90UGxvdChzdWJ0aXNzLCBnZW5lc190b19jaGVjaywgcGxvdC5sZWdlbmQgPSBUKQpgYGAKCkhvdyBiaWcgYXJlIHRoZSBjbHVzdGVycz8KYGBge3J9CnRhYmxlKHN1YnRpc3NAaWRlbnQpCmBgYAoKIyMgQ2hlY2tpbmcgZm9yIGJhdGNoIGVmZmVjdHMKCkNvbG9yIGJ5IG1ldGFkYXRhLCBsaWtlIHBsYXRlIGJhcmNvZGUsIHRvIGNoZWNrIGZvciBiYXRjaCBlZmZlY3RzLgpgYGB7cn0KVFNORVBsb3Qob2JqZWN0ID0gc3VidGlzcywgZG8ucmV0dXJuID0gVFJVRSwgZ3JvdXAuYnkgPSAiY2hhbm5lbCIpCmBgYAoKUHJpbnQgYSB0YWJsZSBzaG93aW5nIHRoZSBjb3VudCBvZiBjZWxscyBpbiBlYWNoIGlkZW50aXR5IGNhdGVnb3J5IGZyb20gZWFjaCBwbGF0ZS4KCmBgYHtyfQp0YWJsZShhcy5jaGFyYWN0ZXIoc3VidGlzc0BpZGVudCksIGFzLmNoYXJhY3RlcihzdWJ0aXNzQG1ldGEuZGF0YSRjaGFubmVsKSkKYGBgCgojIFNhdmUgdGhlIFJvYmplY3QgZm9yIGxhdGVyCldoZW4geW91IHNhdmUgdGhlIGFubm90YXRlZCB0aXNzdWUsIHBsZWFzZSBnaXZlIGl0IGEgbmFtZS4KCmBgYHtyfQpmaWxlbmFtZSA9IGhlcmUoJzAwX2RhdGFfaW5nZXN0JywgJzA0X3Rpc3N1ZV9yb2JqX2dlbmVyYXRlZCcsIAogICAgICAgICAgICAgICAgICAgIHBhc3RlMCgiZHJvcGxldCIsIHRpc3N1ZV9vZl9pbnRlcmVzdCwgIl9zZXVyYXRfdGlzcy5Sb2JqIikpCnByaW50KGZpbGVuYW1lKQpzYXZlKHRpc3MsIGZpbGU9ZmlsZW5hbWUpCmBgYAoKYGBge3J9CiMgVG8gcmVsb2FkIGEgc2F2ZWQgb2JqZWN0CiMgZmlsZW5hbWUgPSBoZXJlKCcwMF9kYXRhX2luZ2VzdCcsICcwNF90aXNzdWVfcm9ial9nZW5lcmF0ZWQnLCAKIyAgICAgICAgICAgICAgICAgICAgICBwYXN0ZTAoImZhY3MiLCB0aXNzdWVfb2ZfaW50ZXJlc3QsICJfc2V1cmF0X3Rpc3MuUm9iaiIpKQojIGxvYWQoZmlsZT1maWxlbmFtZSkKYGBgCgoKIyBFeHBvcnQgdGhlIGZpbmFsIG1ldGFkYXRhCgpTbyB0aGF0IEJpb2h1YiBjYW4gZWFzaWx5IGNvbWJpbmUgYWxsIHlvdXIgY2VsbF9vbnRvbG9neV9jbGFzc3MsIHBsZWFzZSBleHBvcnQgdGhlbSBhcyBhIHNpbXBsZSBjc3YuCgpgYGB7cn0KaGVhZCh0aXNzQG1ldGEuZGF0YSkKYGBgCgoKYGBge3J9CmZpbGVuYW1lID0gaGVyZSgnMDBfZGF0YV9pbmdlc3QnLCAnMDNfdGlzc3VlX2NlbGxfb250b2xvZ3lfY2xhc3NfY3N2JywgCiAgICAgICAgICAgICAgICAgICAgcGFzdGUwKHRpc3N1ZV9vZl9pbnRlcmVzdCwgIl9kcm9wbGV0X2NlbGxfb250b2xvZ3lfY2xhc3MuY3N2IikpCndyaXRlLmNzdih0aXNzQG1ldGEuZGF0YVssYygnY2hhbm5lbCcsJ2NlbGxfb250b2xvZ3lfY2xhc3MnLCdjZWxsX29udG9sb2d5X2lkJyldLCBmaWxlPWZpbGVuYW1lKQpgYGAKCg==